在此使用扫描的方式RegisterAssemblyTypes
注入注册有多种,在此只做常用的 控制器 服务 和Global.asax
项目例子可以参考:https://github.com/nicholaspei/MvcApplication5
如果服务 和控制器是在一个项目中Global.asax.cs是这么配置的
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); // DependencyResolverConfig.Register(); var builder = RegisterService(); DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build())); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } private ContainerBuilder RegisterService() { var builder = new ContainerBuilder(); var baseType = typeof(IService); var assemblys = AppDomain.CurrentDomain.GetAssemblies().ToList(); var AllServices = assemblys .SelectMany(s => s.GetTypes()) .Where(p => baseType.IsAssignableFrom(p) && p != baseType); builder.RegisterControllers(assemblys.ToArray()); builder.RegisterAssemblyTypes(assemblys.ToArray()) .Where(t => baseType.IsAssignableFrom(t) && t != baseType) .AsImplementedInterfaces().InstancePerLifetimeScope(); return builder; }
IService
public interface IService { }
ITestService
public interface ITestService : IService { string Show(); /* { return "你好啊"; }*/ }
实现
public class TestService : ITestService { public string Show() { return "你好啊"; } }
public class HomeController : Controller { private readonly ITestService TestService; public HomeController(ITestService carmodel) { TestService = carmodel; } // ITestService TestService { get; set; } public ActionResult Index() { System.Diagnostics.Trace.WriteLine(TestService.Show()); return View(); }
以上就是service 和controller 在一个项目中的配置方式 controller中必须 在构造函数中注册注入
而还有一种简单的写法跟java 一样
ITestService TestService { get; set; }
就这么一句话
使用场景是iserver 和serverce 接口和实现 和控制器不在一个项目中, 我因为这一句话无法使用,提示了良久才发现这种写法存在问题
下边说说这种方式的配置
Global.asax.cs
protected void Application_Start() { RemoveWebFormEngines(); AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //创建autofac管理注册类的容器实例 var builder = new ContainerBuilder(); SetupResolveRules(builder); //使用Autofac提供的RegisterControllers扩展方法来对程序集中所有的Controller一次性的完成注册 支持属性注入 builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired(); // 把容器装入到微软默认的依赖注入容器中 var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); } private static void SetupResolveRules(ContainerBuilder builder) { //WebAPI只用引用services和repository的接口,不用引用实现的dll。 //如需加载实现的程序集,将dll拷贝到bin目录下即可,不用引用dll var iServices = Assembly.Load("FineAdmin.IService"); var services = Assembly.Load("FineAdmin.Service"); var iRepository = Assembly.Load("FineAdmin.IRepository"); var repository = Assembly.Load("FineAdmin.Repository"); //根据名称约定(服务层的接口和实现均以Services结尾),实现服务接口和服务实现的依赖 builder.RegisterAssemblyTypes(iServices, services) .Where(t => t.Name.EndsWith("Service")) .AsImplementedInterfaces().PropertiesAutowired(); //根据名称约定(数据访问层的接口和实现均以Repository结尾),实现数据访问接口和数据访问实现的依赖 builder.RegisterAssemblyTypes(iRepository, repository) .Where(t => t.Name.EndsWith("Repository")) .AsImplementedInterfaces().PropertiesAutowired(); }
服务 和接口服务 iservice 都一样
控制器端 举例
public IUserService UserService { get; set; } public ILogonLogService LogonLogService { get; set; }
一下有各种的注册写法
// Register services 1 /* var result = builder.RegisterAssemblyTypes(typeof(MvcApplication).Assembly) .Where(x =>typeof(IService).IsAssignableFrom(x)) .AsImplementedInterfaces() .InstancePerRequest(); */ /* 2 var result = builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) .Where(x => typeof(IService).IsAssignableFrom(x)) .AsImplementedInterfaces() .InstancePerRequest();*/ /* 3 */var result = builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) .Where(t => t.Name.EndsWith("IService")) .AsImplementedInterfaces() .InstancePerRequest(); // var builder = new ContainerBuilder(); /* 4 var baseType = typeof(IService); var assemblys = AppDomain.CurrentDomain.GetAssemblies().ToList(); var AllServices = assemblys .SelectMany(s => s.GetTypes()) .Where(p => baseType.IsAssignableFrom(p) && p != baseType); builder.RegisterControllers(assemblys.ToArray()); builder.RegisterAssemblyTypes(assemblys.ToArray()) .Where(t => baseType.IsAssignableFrom(t) && t != baseType) .AsImplementedInterfaces().InstancePerLifetimeScope(); // return builder; DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));*/
了解了这些似乎配置复杂一点的还是出现各种问题,比如泛型接口
通过一步步的抓包加深了解
这是那个测试项目
这条代码应该是获取当前项目使用的所有程序集转list
在此是只为当前项目名的程序集,下边可以看到红框内当前项目名在里边
接下来查找程序集里边IService类
这句在此没有什么实际用处
而此句
是注册控制器内的构造函数的相关的, 注册所有控制类还有一种写法 省一行代码
// 注册所有的Controller
// builder.RegisterControllers(Assembly.GetExecutingAssembly());
如果没有那句,
isAssignableFrom()方法是判断是否为某个类的父类
限于没深入研究更为复杂的 接口加抽象类 类似以下 的结构的注入配置,决定放弃 service 和 controller Repositories 在同一项目的情况, 如果想用注入最好是三者分开项目,真是方便配置autofac
总结就是autofac 如果小项目就不要用了, new 来new去也不错啊, 一旦用了这那玩意 ,还要配置总接口,有些还有接口下再加具体接口,接口 加上后,显得代码也够臃肿,改了一个地方,考虑接口里也得加上,
再说有些人说省new 省资源, 这一点从线程角度,个人理解, 每次请求iis会生成一个线程的,关于线程大家都知道,会把对象,函数之类的组到一个单独的堆里.从这一点理解上来看,并没有省新建对象的啊..
个人理解,有机会再深入了解一下请求线程是如何使用资源的.
留下调试过程中的配置方法各种
using Autofac; using Autofac.Integration.Mvc; using RegisterAssemblyDemo.Services; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Web; using System.Web.Compilation; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; namespace RegisterAssemblyDemo { public class MvcApplication : System.Web.HttpApplication { /* protected void Application_Start() { AreaRegistration.RegisterAllAreas(); // DependencyResolverConfig.Register(); var builder = RegisterService3();//RegisterService(); var container = builder.Build(); using (var scope = container.BeginLifetimeScope()) { var service = scope.Resolve<IService>(); // If IService is registered, it will be resolved; if // it isn't registered, the return value will be null. var servic = scope.ResolveOptional<IService>(); ITestService provider; if (scope.TryResolve<ITestService>(out provider)) { provider.Show(); // Do something with the resolved provider value. } } DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } */ protected void Application_Start() { RemoveWebFormEngines(); AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //创建autofac管理注册类的容器实例 var builder = new ContainerBuilder(); SetupResolveRules(builder); //使用Autofac提供的RegisterControllers扩展方法来对程序集中所有的Controller一次性的完成注册 支持属性注入 builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired(); // 把容器装入到微软默认的依赖注入容器中 var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); } private static void SetupResolveRules(ContainerBuilder builder) { //WebAPI只用引用services和repository的接口,不用引用实现的dll。 //如需加载实现的程序集,将dll拷贝到bin目录下即可,不用引用dll var iServices = Assembly.Load("FineAdmin.IService"); var services = Assembly.Load("FineAdmin.Service"); var iRepository = Assembly.Load("FineAdmin.IRepository"); var repository = Assembly.Load("FineAdmin.Repository"); //根据名称约定(服务层的接口和实现均以Services结尾),实现服务接口和服务实现的依赖 builder.RegisterAssemblyTypes(iServices, services) .Where(t => t.Name.EndsWith("Service")) .AsImplementedInterfaces().PropertiesAutowired(); //根据名称约定(数据访问层的接口和实现均以Repository结尾),实现数据访问接口和数据访问实现的依赖 builder.RegisterAssemblyTypes(iRepository, repository) .Where(t => t.Name.EndsWith("Repository")) .AsImplementedInterfaces().PropertiesAutowired(); } private void RegisterService2() { var builder = new ContainerBuilder(); // Register 方式指定具体类 /* builder.Register(c => new InjectionTestService()).As<IService>().InstancePerDependency(); // RegisterType 方式指定具体类 builder.RegisterType<InjectionTestService>().As<IService>().InstancePerDependency();*/ // 自动注册的方式 // 获取包含继承了IService接口类的程序集 var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>() .Where( assembly => assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(IService))) != null ); // RegisterAssemblyTypes 注册程序集 var enumerable = assemblies as Assembly[] ?? assemblies.ToArray(); if (enumerable.Any()) { builder.RegisterAssemblyTypes(enumerable) .Where(type => type.GetInterfaces().Contains(typeof(IService))).AsImplementedInterfaces().InstancePerDependency(); } } private ContainerBuilder RegisterService3() { var builder = new ContainerBuilder(); builder.RegisterControllers(typeof(MvcApplication).Assembly); // 自动注册的方式 // 获取包含继承了IService接口类的程序集 var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>() .Where( assembly => assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(IService))) != null ); // RegisterAssemblyTypes 注册程序集 var enumerable = assemblies as Assembly[] ?? assemblies.ToArray(); if (enumerable.Any()) { builder.RegisterAssemblyTypes(enumerable) .Where(type => type.GetInterfaces().Contains(typeof(IService))).AsImplementedInterfaces().InstancePerDependency(); } // 获取包含继承了IService接口类的程序集 var assemblies2 = BuildManager.GetReferencedAssemblies().Cast<Assembly>() .Where( assembly => assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(IBaseService<>))) != null ); // RegisterAssemblyTypes 注册程序集 var enumerable2 = assemblies2 as Assembly[] ?? assemblies2.ToArray(); if (enumerable2.Any()) { builder.RegisterAssemblyTypes(enumerable2) .Where(type => type.GetInterfaces().Contains(typeof(IBaseService<>))).AsImplementedInterfaces().InstancePerDependency(); } return builder; } private ContainerBuilder RegisterService4() { var builder = new ContainerBuilder(); builder.RegisterControllers(typeof(MvcApplication).Assembly); var res = builder.RegisterAssemblyTypes(typeof(MvcApplication).Assembly) .Where(x => x.IsClass && !x.IsAbstract && typeof(IService).IsAssignableFrom(x)) .AsImplementedInterfaces() .InstancePerRequest(); return builder; } private ContainerBuilder RegisterService() { var builder = new ContainerBuilder(); // 注册所有的Controller // builder.RegisterControllers(Assembly.GetExecutingAssembly()); var baseType = typeof(IService); var assemblys = AppDomain.CurrentDomain.GetAssemblies().ToList(); /* var AllServices = assemblys .SelectMany(s => s.GetTypes()) .Where(p => baseType.IsAssignableFrom(p) && p != baseType); */ builder.RegisterControllers(assemblys.ToArray()); builder.RegisterAssemblyTypes(assemblys.ToArray()) .Where(t => baseType.IsAssignableFrom(t) && t != baseType) .AsImplementedInterfaces().InstancePerLifetimeScope(); return builder; } /// <summary> /// 移除webform试图引擎 /// </summary> void RemoveWebFormEngines() { var viewEngines = ViewEngines.Engines; var webFormEngines = viewEngines.OfType<WebFormViewEngine>().FirstOrDefault(); if (webFormEngines != null) { viewEngines.Remove(webFormEngines); } } } }