zoukankan      html  css  js  c++  java
  • 也说Autofac在MVC的简单实践:破解在Controller构造函数中的实例化

    相信大家对Autofac并不陌生,很多人都在使用。本文只是介绍一下本人在使用时的一点想法总结。

    在使用一个框架时,肯定要去它的官网查阅一下。autofac的官网给出了一些经典的使用案例。如注册容器:

    var builder = new ContainerBuilder();
     
    // Register individual components
    builder.RegisterInstance(new TaskRepository)
           .As<ITaskRepository>();
    builder.RegisterType<TaskController>();
    builder.Register(c => new LogManager(DateTime.Now))
           .As<ILogger>();
     
    // Scan an assembly for components
    builder.RegisterAssemblyTypes(myAssembly)
           .Where(t => t.Name.EndsWith("Repository"))
           .AsImplementedInterfaces();
     
    var container = builder.Build();
    public class TaskController
    {
      private ITaskRepository _repository;
      private ILogger _logger;
     
      // Autofac will automatically find the registered
      // values and pass them in for you.
      public TaskController(
        ITaskRepository repository,
        ILogger logger)
      {
        this._repository = repository;
        this._logger = logger;
      }
    }

    在这里先重点说一下在mvc中的使用,如上代码可见,在一个请求到达时,需要对controller进行实例化,而正如autofac官网所说“ If there is more than one constructor on a component type, Autofac will use the constructor with the most resolvable parameters. ”,如果有多个带参构造函数,autofac默认使用参数最多的构造函数。在上面代码中,即便在一个action中,你只用了_ logger ,那么_ repository 也依旧需要被autofac解析。

    而在mvc的具体应用中,我们可能会使用多重继承,如下图的结构

    在这种情况下,每个controller可能会有很多构造函数,在每个请求到达时,都需要实例化相当一部分的变量。本人没有研究过这种实例化是否会影响效率,只是觉得这样对于开发来讲过于繁琐,且不利于维护,代码也并不流畅。我的想法是在action中,在需要的点去实例化。

    经过一些查阅,autofac官方提供了很多库,发现其中Autofac.Mef是可以用另一种方式实现达到同样的效果。文档的介绍只有一句话“ The MEF integration allows you to expose extensibility points in your Autofac applications using the   Managed Extensibility Framework . ”  mef可能主要用来在对已经开发完毕的版本做补充的时候使用。如某个系统已经开发结束并部署运行了,这时候会有些功能的增加和扩展,在不修改原版本的前提下,使用mef可以将后补充的功能ioc到原系统。mef需要引用ystem.ComponentModel.Composition.dll 库。

    先不说别的了,代码说明一切。在接口实现上需要加入ExportAttribute,如:

    [Export(typeof(ICustomerBusiService))]
        public class CustomerBusiService : ICustomerBusiService

     注意,ICustomerBusiService不用做任何的描述,只描述其实现CustomerBusiService即可。为了达到我的目的,我在顶层的controller中增加了一个获取实例的方法,以便action中根据自己的需要获取实例化:

    public abstract class AbstractController : Controller
        {
            private static IAutofacResolver _resolver = new AutofacResolver();
            protected T GetService<T>()
            {
                return _resolver.GetService<T>();
            }
        }
    下面展示一下IAutofacResolver及其实现AutofacResolver
    public interface IAutofacResolver
        {
            T GetService<T>();
        }
    
        public class AutofacResolver : IAutofacResolver
        {
            private Autofac.IContainer _container;
    
            public T GetService<T>()
            {
                if (_container == null || !_container.IsRegistered<T>())
                {
                    RegisterPartsFromReferencedAssemblies();
                }
                return _container.Resolve<T>();
            }
    
            private void RegisterPartsFromReferencedAssemblies()
            {
                var asses = BuildManager.GetReferencedAssemblies().Cast<Assembly>();
                var assemblyCatalogs = asses.Select(x => new AssemblyCatalog(x));
                var catalog = new AggregateCatalog(assemblyCatalogs);
    
                var builder = new ContainerBuilder();
                builder.RegisterComposablePartCatalog(catalog);
                _container = builder.Build();
                DependencyResolver.SetResolver(new AutofacDependencyResolver(_container));
            }
        }

    有了这样一个结构,那么在具体的controller中我不需要有构造函数,在acton中只要调用GetService<T>()就可以获取我需要的实例。

    public class AccountController : AbstractMvcController
        {
            [HttpPost]
            public ActionResult Register(Customer customer)
            {
                var ibsCusomter = GetService<ICustomerBusiService>();
                ibsCusomter.Register(customer);
                return View();
            }
        }

    以上就是全部内容。本文并没有针对复杂的autofac应用进行说明,比如注册复杂的模型,激活事件等。只是对比较简单普遍的autofac的使用进行一些分析,个人认为mvc的站点开发中,不太会用到比较复杂的东西,因为每个用户请求都是独立的,又有并发的问题,所以autofac的单实例也基本不会考虑。

  • 相关阅读:
    directX根据设备类GUID查询所属的filter 分类: DirectX 2014-09-20 08:34 501人阅读 评论(0) 收藏
    directX枚举系统设备类 分类: DirectX 2014-09-20 08:30 491人阅读 评论(0) 收藏
    INF 右键安装驱动以及卸载 分类: 生活百科 2014-09-18 14:03 573人阅读 评论(0) 收藏
    AVStream ddk 翻译 分类: DirectX 2014-09-13 10:43 534人阅读 评论(0) 收藏
    SCADA系统 分类: 生活百科 2014-09-11 17:26 627人阅读 评论(0) 收藏
    VxWorks操作系统shell命令与调试方法总结 分类: vxWorks 2014-08-29 14:46 1191人阅读 评论(0) 收藏
    winhex中判断+MBR+DBR+EBR方法 分类: VC++ 2014-08-27 09:57 443人阅读 评论(0) 收藏
    解析FAT16文件系统 分类: 生活百科 2014-08-27 09:56 580人阅读 评论(1) 收藏
    win9x_win2k下对物理磁盘的操作 分类: VC++ 磁盘的扇区读写 2014-08-27 09:55 421人阅读 评论(0) 收藏
    FAT32文件系统的存储组织结构(二) 分类: VC++ 2014-08-27 09:15 467人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/Alex80/p/5595515.html
Copyright © 2011-2022 走看看