前面学习了autofac这个依赖注入组件,原本是打算写在一块儿的,由于这个组件没打算像autofac同样详细的写,只是写下之前本身鼓捣玩搭建框架而后使用的一个依赖注入组件,而且也是进行了封装使用。不打算做为学习知识,仅做为使用封装记录的。html
没想autofac写着写着篇幅有点长,就单独看成一个封装类记录一下吧。技术就和东西差很少长时间不使用就容易忘记。web
上一篇autofac地址:【AutoFac】依赖注入和控制反转的使用mvc
别的不说引用仍是要简单说一下的,在使用前要引用dll:框架
我这里是把Unity组件和项目业务进行了分层全部我这个组件至关于在一个独立的项目中,单独的封装到了IOC文件夹下建立,这里不介绍整个解决方案了只对这个介绍下,大体的结构以下:ide
这个是主要类,容器的注入和获取容器里面的类至关于Unity的入口调用和请求都经过他,这个封装有一个好处就是统一调用(废话)。post
/// <summary>
/// 依赖注入之区域注入方式
/// 没有写入到配置文件可传参注入
/// </summary>
public class Ioc
{
private static readonly UnityContainer _container; static Ioc() { _container = new UnityContainer(); } public static void RegisterInheritedTypes(Assembly assembly, Type baseType) { _container.RegisterInheritedTypes(assembly, baseType); } public static void Register<TInterface, TImplementation>() where TImplementation : TInterface { _container.RegisterType<TInterface, TImplementation>(); } public static T Get<T>() { return _container.Resolve<T>(); } }
而后有一个Unity扩展注册方法:学习
public static class UnityContainerExtensions
{
/// <summary>
/// Unity扩展注册方法
/// </summary>
/// <param name="container"></param>
/// <param name="assembly"></param>
/// <param name="baseType"></param>
public static void RegisterInheritedTypes(this IUnityContainer container, Assembly assembly, Type baseType) { var allTypes = assembly.GetTypes(); var baseInterfaces = baseType.GetInterfaces(); foreach (var type in allTypes) { if (type.BaseType != null && type.BaseType.GenericEq(baseType)) { var typeInterface = type.GetInterfaces().FirstOrDefault(x => !baseInterfaces.Any(bi => bi.GenericEq(x))); if (typeInterface == null) { continue; } container.RegisterType(typeInterface, type); } } } }
这个很关键哦,这里再说下我这里其实不是每一个类都要写一遍注册,而是全部业务类继承于一个底层抽象类ServiceBase。而后传入程序集和类型,就会把当前程序集下的全部这个类型注册进去。测试
例如我有UserServer和UserServerTwo两个业务类,我让他都继承ServiceBase抽象类,固然他们仍然要实现本身的服务接口的就拿UserServer举例吧:this
这样我到时候使用只须要注册一遍就把这两个服务同时注入了。什么好处在哪里,第一注册代码写少了,第二实现区域化分类。url
使用根据mvc的控制器区域进行单独注册便可:
public override void RegisterArea(AreaRegistrationContext context)
{
//注册使用代码,先注册后使用
Ioc.RegisterInheritedTypes(typeof(Server_Areas.Admin.IUserServer).Assembly, typeof(ServiceBase)); context.MapRoute( "AdminAreas_default", "AdminAreas/{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional }, new string[] { "LayerFrame.Areas." + this.AreaName + ".Controllers" } ); }
而后在该区域控制器使用:
public ActionResult Index()
{
//测试日志
LogHelp.WriteFile("deBug", "这是日志输出哦"); //数据操做 var service = Ioc.Get<Server_Areas.Admin.IUserServer>(); //添加数据 UserInfor user = new UserInfor(); user.userAccount = "test001"; user.userPwd = "123456"; user.userPhone = "0530123456"; user.userRealName = "真实姓名"; user.userSex = 0; user.userPhone = "0530123456"; user.userRemark = "备注内容"; user.addTime = DateTime.Now; int count = service.UserAdd(user); var data= service.GetData(); ViewBag.data = service.GetData(); return View(); }
每次注入服务类是很麻烦的,好比修改了增长了,总不能一直去修改代码吧,老是很差的,因此咱们也能够写到配置文件统一管理,比较方便(其实我上面封装的也很方便了)。这个比上面好的是在于不用进行区域注册了。所有统一注册了。
这里我又一个地方是使用了之前的一篇【Config】类库读取本身的配置文件,配置文件的扩展,因此我是单独在IOC文件夹下建立了对应的web.config文件,若是写在项目跟web.config文件把注释那句话取消便可。
public class UnityFactory
{
private static IUnityContainer _iUnityContainer = null; private UnityFactory() { } static UnityFactory() { ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "IOC\\Unity.Config"); Configuration configuration = LibConfig.InitConfig("IOC\\Unity"); UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName); // UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName); _iUnityContainer = new UnityContainer(); try { section.Configure(_iUnityContainer, "MyContainer"); } catch (Exception e) { throw; } } public static IUnityContainer GetContainerInstance() { return _iUnityContainer; } public static T GetServer<T>() { try { return _iUnityContainer.Resolve<T>(); } catch (Exception e) { throw; } } }
使用就特别简单啦:
public ActionResult Test() {
try { var service = UnityFactory.GetServer<Server_Areas.Admin.UserServer>(); var data = service.GetData(); } catch (Exception e) { } return View(); }