您的位置:首页 > 其它

我的开发框架(WinForm)3

2013-08-28 10:34 169 查看
今天继续给大家介绍核心库的IOC的使用,在我的框架里,IOC使用的比较简单,主要是用于解除模块间的耦合和实例化接口。

1、接口说明,IocContainer接口比较简单只有3个方法,但是是系统中用的最多的。

IocContainerpublicinterfaceIocContainer:IDisposable
{
///<summary>
///获得某个接口的一组实例
///</summary>
///<typeparamname="T"></typeparam>
///<returns>IEnumerable{``0}.</returns>
IEnumerable<T>GetInstances<T>();
///<summary>
///获取接口的一个实例
///</summary>
///<typeparamname="T">接口的类型</typeparam>
///<returns>,如果没有注册该接口,则返回null</returns>
TGetInstance<T>();

///<summary>
///根据关键字获取对象
///</summary>
///<paramname="key">Thekey.</param>
///<returns>System.Object.</returns>
objectGetInstance(stringkey);
}


2、接口的实现。我用的是AutoFac,选用他基于2个方面的考虑,第一是对MEf和泛型的支持,第二是效率





园子里的Leepy已经对比过主流的IOC框架,/article/4758623.html,

时间比较早了,有兴趣的可以用最新的类库测试一下。

AutoFac有对MEF的扩展插件,很方便。这样做的好处是,我可以只在核心模块中引用AutoFac,业务模块中无需引用,用Mef标示即可,对于团队开发来说,他无需再了解AutoFac如何使用。

不多说了,上代码

ContainerBuilderbuilder;
IContainer_container=null;
publicAutofacContainer(paramsComposablePartCatalog[]catalogs)
{
builder=newContainerBuilder();

boolisRegisterOrm=false;
foreach(varitemincatalogs)
{
builder.RegisterComposablePartCatalog(item);

if(itemisDirectoryCatalog&&!isRegisterOrm)
{
DirectoryCatalogdir=itemasDirectoryCatalog;
}
}

}

其中ComposablePartCatalog是MEF的东东,ContainerBuilder是AutoFac的东西,这一步主要是讲Mef的组件注册到AutoFac里。然后通过IContainerContainer=builder.Build(Autofac.Builder.ContainerBuildOptions.IgnoreStartableComponents);这个方法初始化完成,我测试的时候发现这个方法,只能执行一次,第二次就报错。对应IocContainer.GetInstance这个方法的实现就简单了,调用Autofac的对应的方法就行了boolbl=Container.TryResolve<T>(outt);返回t就OK了,




需要注意的是,Mef对泛型支持的不太好,所以需要单独处理。

对于IRepository<T>和IRepository<T,Tid>接口来说,最理想的的情况是,我需要处理哪个实体类,就直接用varrep=IocContainer.GetInstance<IRepository<T>>()这种方式,就能到IRepository<T>的实例,然后进行后面的操作了。

首先获得加载文件的所有Assembly,然后判断他的名字是否以"Repository`1"结尾,然后调用AutoFac的泛型注册方法,注册,

Assemblyass=Assembly.LoadFile(filepath);
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;
}

由于本人对Autofac也是一知半解,只能用笨办法,肯定有好的办法,只是我还不知道.望园子里的高手指点一下。
通过IocContainer接口,我们就可以创建并使用所有的接口了。
3、使用
在Core中我设计了一个全局静态类ApplicationEx,把IocContainer接口作为一个只读属性暴露出来,接口的实例化操作都在ApplicationEx的初始化中完成,在其他启动的时候,初始化ApplicationEx一次,保证IOC被初始化一次,后面所有模块的直接使用ApplicationEx的Container属性。这就达到了我们想要的目的。
4、扩展
我是一个比较懒的人,不想每次都写varrep=IocContainer.GetInstance<IRepository<T>>(),觉得写得有点多
然后在Core里给IocContainer增加了个扩展方法,
///<summary>
///获得数据操作仓库接口
///</summary>
///<typeparamname="T">操作的实体类</typeparam>
///<returns>IRepository{``0}.</returns>
publicstaticIRepository<T>GetRepository<T>(thisIocContainerioc)whereT:EntityBase,new()
{
returnioc.GetInstance<IRepository<T>>();
}

以后所有的模块调用就直接写varrep=IocContainer.GetRepository<T>(),又少写了10几个字符,呵呵呵。

今天就到这里吧,后面接着给大家介绍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: