今天繼續給大家介紹核心庫的IOC的使用,在我的框架里,IOC使用的比較簡單,主要是用於解除模塊間的耦合和實例化接口。
1、接口說明,IocContainer接口比較簡單只有3個方法,但是是系統中用的最多的。
IocContainer
2、接口的實現。我用的是AutoFac,選用他基於2個方面的考慮,第一是對MEf和泛型的支持,第二是效率
園子里的Leepy 已經對比過主流的IOC框架,http://www.cnblogs.com/liping13599168/archive/2011/07/17/2108734.html,
時間比較早了,有興趣的可以用最新的類庫測試一下。
AutoFac有對MEF的擴展插件,很方便。這樣做的好處是,我可以只在核心模塊中引用AutoFac ,業務模塊中無需引用,用Mef標示即可,對於團隊開發來說,他無需再了解AutoFac如何使用。
不多說了,上代碼
ContainerBuilder builder;
IContainer _container = null;
public AutofacContainer(params ComposablePartCatalog[] catalogs)
{
builder = new ContainerBuilder();
bool isRegisterOrm = false;
foreach (var item in catalogs)
{
builder.RegisterComposablePartCatalog(item);
if (item is DirectoryCatalog && !isRegisterOrm)
{
DirectoryCatalog dir=item as DirectoryCatalog;
}
}
}
其中ComposablePartCatalog 是MEF的東東,ContainerBuilder 是AutoFac的東西, 這一步主要是講Mef的組件注冊到AutoFac里。然后通過 IContainer Container=builder.Build(Autofac.Builder.ContainerBuildOptions.IgnoreStartableComponents); 這個方法初始化完成,我測試的時候發現這個方法,只能執行一次,第二次就報錯。對應IocContainer.GetInstance 這個方法的實現就簡單了,調用Autofac的對應的方法就行了bool bl = Container.TryResolve<T>(out t);返回t 就OK了,
需要注意的是,Mef對泛型支持的不太好,所以需要單獨處理。
對於IRepository<T>和IRepository<T,Tid>接口來說,最理想的的情況是,我需要處理哪個實體類,就直接用var rep= IocContainer.GetInstance<IRepository<T>>() 這種方式,就能到IRepository<T>的實例,然后進行后面的操作了。
首先獲得加載文件的所有 Assembly,然后判斷他的名字是否以"Repository`1"結尾,然后調用AutoFac的泛型注冊方法,注冊,
Assembly ass = Assembly.LoadFile(filepath);由於本人對Autofac 也是一知半解,只能用笨辦法,肯定有好的辦法,只是我還不知道.望園子里的高手指點一下。
Type[] types = ass.GetTypes().Where(t => t.Name.EndsWith("Repository`1")).ToArray();
if (types.Length > 0 && types[0].Name != "IRepository`1")
{
builder.RegisterGeneric(types[0]).As(typeof(IRepository<>));
isload = true;
}
/// <summary> /// 獲得數據操作倉庫接口 /// </summary> /// <typeparam name="T">操作的實體類</typeparam> /// <returns>IRepository{``0}.</returns> public static IRepository<T> GetRepository<T>(this IocContainer ioc) where T : EntityBase, new() { return ioc.GetInstance<IRepository<T>>(); }
以后所有的模塊調用就直接寫var rep= IocContainer.GetRepository<T>(),又少寫了10幾個字符,呵呵呵。
今天就到這里吧,后面接着給大家介紹。

