博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
也说Autofac在MVC的简单实践:破解在Controller构造函数中的实例化 - winhu
阅读量:7137 次
发布时间:2019-06-28

本文共 3567 字,大约阅读时间需要 11 分钟。

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

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

var builder = new ContainerBuilder(); // Register individual componentsbuilder.RegisterInstance(new TaskRepository)       .As
(); builder.RegisterType
(); builder.Register(c => new LogManager(DateTime.Now)) .As
(); // 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    . ”  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
() { return _resolver.GetService
(); } }
下面展示一下IAutofacResolver及其实现AutofacResolver
public interface IAutofacResolver    {        T GetService
(); } public class AutofacResolver : IAutofacResolver { private Autofac.IContainer _container; public T GetService
() { if (_container == null || !_container.IsRegistered
()) { RegisterPartsFromReferencedAssemblies(); } return _container.Resolve
(); } private void RegisterPartsFromReferencedAssemblies() { var asses = BuildManager.GetReferencedAssemblies().Cast
(); 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
(); ibsCusomter.Register(customer); return View(); } }

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

转载地址:http://omcrl.baihongyu.com/

你可能感兴趣的文章
二进制、十进制、十六进制相互转换
查看>>
精通MVC网站、MVVM开发模式、Razor语法
查看>>
企业IT架构介绍
查看>>
Watchdog
查看>>
UVALive 6889 City Park 并查集
查看>>
CentOS6.8配置GO语言开发环境
查看>>
sed笔记
查看>>
一个简单的无限滚动的加载数据实现
查看>>
高铁在高速运行时的电力是如何提供的?
查看>>
fedora23的打印服务
查看>>
线程中消费者生产者的实例代码(使用Lock类)
查看>>
转-ubuntu清理卸载wine的残余项目
查看>>
Unity工程3D和2D开发模式切换
查看>>
关于天津中软国际ETC培训中心的见与闻
查看>>
linux设置开机服务自动启动/关闭自动启动命令
查看>>
IP地址网段规划
查看>>
单台服务器上安装Hadoop和Hive十五分钟教程
查看>>
LDA-线性判别分析(一)
查看>>
算法入门系列一--DP初步
查看>>
【转】C++中了类继承和调用父类的构造函数方法
查看>>