.net core2.0下Ioc容器Autofac使用
Autofac基本使用
Autofac是一款輕量級的IOC框架,使用率上還是挺高的,官方網站http://autofac.org,源碼下載地址https://github.com/autofac/Autofac。
下面以狗的列子來介紹autofac,nuget搜索Autofac進行安裝
public interface IDog
? ? {
? ? ? ? /// <summary>
? ? ? ? /// 品種
? ? ? ? /// </summary>
? ? ? ? string Breed { get; }
? ? ? ? /// <summary>
? ? ? ? /// 名稱
? ? ? ? /// </summary>
? ? ? ? string Name { get; }
? ? }
? ? /// <summary>
? ? /// 薩摩耶
? ? /// </summary>
? ? public class Samoyed : IDog
? ? {
? ? ? ? /// <summary>
? ? ? ? /// 品種
? ? ? ? /// </summary>
? ? ? ? public string Breed
? ? ? ? {
? ? ? ? ? ? get
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return "Samoyed(薩摩耶)";
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// 名稱
? ? ? ? /// </summary>
? ? ? ? public string Name
? ? ? ? {
? ? ? ? ? ? get
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return "小黃";
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? /// <summary>
? ? /// 藏獒
? ? /// </summary>
? ? public class TibetanMastiff : IDog
? ? {
? ? ? ? /// <summary>
? ? ? ? /// 品種
? ? ? ? /// </summary>
? ? ? ? public string Breed
? ? ? ? {
? ? ? ? ? ? get
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return "Mastiff Class(獒犬類)";
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// 名稱
? ? ? ? /// </summary>
? ? ? ? public string Name
? ? ? ? {
? ? ? ? ? ? get
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return "小黑";
? ? ? ? ? ? }
? ? ? ? }
? ? }
1.RegisterType?
public static void Register()
{
? ? var builder = new ContainerBuilder();
? ? //注冊Samoyed指定為IDog實現
? ? builder.RegisterType<Samoyed>().As<IDog>();
? ? builder.RegisterType<TibetanMastiff>().As<IDog>();
? ? using (var container = builder.Build())
? ? {
? ? ? ? var dogs = container.Resolve<IEnumerable<IDog>>();
? ? ? ? foreach (var dog in dogs)
? ? ? ? {
? ? ? ? ? ? ?Console.WriteLine($"名稱:{dog.Name},品種:{dog.Breed}");
? ? ? ? }
? ? }
}
2.RegisterAssemblyTypes
public static void RegisterAssemblyTypes()
{
? ? var builder = new ContainerBuilder();
? ? //注冊程序集下所有類型
? ? builder.RegisterAssemblyTypes(typeof(Program).Assembly).AsImplementedInterfaces();
? ? using (var container = builder.Build())
? ? {
? ? ? ? var dogs = container.Resolve<IEnumerable<IDog>>();
? ? ? ? foreach (var dog in dogs)
? ? ? ? {
? ? ? ? ? ? Console.WriteLine($"名稱:{dog.Name},品種:{dog.Breed}");
? ? ? ? }
? ? }
}
直接注冊程序集下的所有類型,AsImplementedInterfaces(讓具體實現類型,可以該類型繼承的所有接口類型找到該實現類型)
3.RegisterInstance
TibetanMastiff d = new TibetanMastiff(); builder.RegisterInstance(d).As<IDog>();4.RegisterModule
這種模式需要使用配置文件進行注冊,個人更喜歡代碼直接注冊的方式,畢竟配置文件修改容易遺忘和出錯。這里就不介紹該方式了。?
? ? ??
遺留問題:上面的注冊代碼,自己寫寫demo的時候沒啥問題。但是運用到項目里面就很繁瑣了,需要自己一個個類型注冊,后面會提供解決方案。
?
.net core MVC與Autofac
1.首先nuget下載Autofac和Autofac.Extensions.DependencyInjection引用
2.替換mvc自帶的DI框架
將Startup.cs中的ConfigureServices返回類型改為IServiceProvider
public IServiceProvider ConfigureServices(IServiceCollection services)
{
? ? services.AddMvc();
? ? var builder = new ContainerBuilder();
? ? builder.Populate(services);
? ? builder.RegisterAssemblyTypes(typeof(Startup).Assembly).AsImplementedInterfaces();
? ? var Container = builder.Build();
? ? return new AutofacServiceProvider(Container);
}
屬性注入
Autofac默認是構造函數注入
[Route("api/[controller]")]
public class ValuesController : Controller
{
? ? private readonly IEnumerable<IDog> dogs;
? ? public ValuesController(IEnumerable<IDog> _dogs)
? ? {
? ? ? ? dogs = _dogs;
? ? }
? ? // GET api/values
? ? [HttpGet]
? ? public IEnumerable<string> Get()
? ? {
? ? ? ? List<string> list = new List<string>();
? ? ? ? foreach (var dog in dogs)
? ? ? ? {
? ? ? ? ? ? list.Add($"名稱:{dog.Name},品種:{dog.Breed}");
? ? ? ? }
? ? ? ? return list.ToArray(); ;
? ? }
}
?
使用過mef的可能更喜歡屬性注入的方式,那么使用autofac怎么實現屬性注入呢?
1.注冊系統所有Controller,由Autofac創建
var IControllerType = typeof(ControllerBase); builder.RegisterAssemblyTypes(assembly).Where(t => IControllerType.IsAssignableFrom(t) && t != IControllerType).PropertiesAutowired();?上面這段代碼的解釋:注冊所有程序集下繼承ControllerBase的類型,PropertiesAutowired 允許屬性注入。
2.替換系統默認Controller創建器
services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());services.AddMvc();注意:Replace代碼放在AddMvc之前
Replace代碼的意思:使用ServiceBasedControllerActivator替換DefaultControllerActivator(意味著框架現在會嘗試從IServiceProvider中解析控制器實例,也就是return new AutofacServiceProvider(Container);
)
3.使用屬性注入
[Route("api/[controller]")]
? ? public class ValuesController : Controller
? ? {
? ? ? ? public IEnumerable<IDog> dogs { get; set; }
? ? ? ? [HttpGet]
? ? ? ? public IEnumerable<string> Get()
? ? ? ? {
? ? ? ? ? ? List<string> list = new List<string>();
? ? ? ? ? ? foreach (var dog in dogs)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? list.Add($"名稱:{dog.Name},品種:{dog.Breed}");
? ? ? ? ? ? }
? ? ? ? ? ? return list.ToArray(); ;
? ? ? ? }
? ? }
至此完成了使用Autofac實現屬性注入
Autofac+Castle實現AOP
1.首先nuget下載Autofac.Extras.DynamicProxy引用
2.編寫攔截器
public class LogInterceptor : IInterceptor
{
? ? public void Intercept(IInvocation invocation)
? ? {
? ? ? ? Console.WriteLine("你正在調用方法 \"{0}\"? 參數是 {1}... ",
? ? ? ? ? ?invocation.Method.Name,
? ? ? ? ? ?string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));
? ? ? ? invocation.Proceed();
? ? ? ? if (invocation.ReturnValue != null && invocation.ReturnValue is string)
? ? ? ? {
? ? ? ? ? ? //在返回接口上拼上LogInterceptor
? ? ? ? ? ? invocation.ReturnValue += " LogInterceptor";
? ? ? ? }
? ? ? ? Console.WriteLine("方法執行完畢,返回結果:{0}", invocation.ReturnValue);
? ? ? ? Console.WriteLine("開始記錄日志....");
? ? }
}
3.開啟攔截(接口攔截器? 類攔截器)?
builder.RegisterType<LogInterceptor>();
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces()
? ? .EnableInterfaceInterceptors();
var IControllerType = typeof(ControllerBase);
builder.RegisterAssemblyTypes(assembly).Where(t => IControllerType.IsAssignableFrom(t) && t != IControllerType).PropertiesAutowired()
? ? .EnableClassInterceptors();
var Container = builder.Build();
開啟接口攔截器:EnableInterfaceInterceptors 開啟類攔截器:EnableClassInterceptors[Intercept(typeof(LogInterceptor))] [Route("api/[controller]")]public class ValuesController : Controller { }[Intercept(typeof(LogInterceptor))]public class Samoyed : IDog { }這種使用方式需要自己指定在哪個類上使用,還有一種全局攔截器
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces().EnableInterfaceInterceptors()? ?.InterceptedBy(typeof(LogInterceptor));
?
代碼封裝簡單使用
先列出使用過程中遇到的幾個問題,然后再給出解決方案
1:如何簡單注冊代碼里面的所有類型
2.如何注冊單例和普通對象
3.封裝好的代碼怎么支持用戶特殊化注冊需求
為了解決上述問題,這里給出了幾個約束
單例對象需繼承的接口:ISingletonDependency? 普通對象需繼承的接口:ITransientDependency 特殊化注冊接口:IDependencyRegistrar
通過這幾個約束,在初始化時找所有程序集 繼承ISingletonDependency ,ITransientDependency 接口的對象進行類型注冊
/// <summary>/// 單例接口 ? ?/// </summary>public interface ISingletonDependency{}
/// <summary>
? ? /// 所有接口的依賴接口,每次創建新實例
? ? /// </summary>
? ? /// <remarks>
? ? /// 用于Autofac自動注冊時,查找所有依賴該接口的實現。
? ? /// 實現自動注冊功能
? ? /// </remarks>
? ? public interface ITransientDependency
? ? {
? ? }
/// <summary>
? ? /// 依賴注冊接口
? ? /// </summary>
? ? public interface IDependencyRegistrar
? ? {
? ? ? ? /// <summary>
? ? ? ? /// Register services and interfaces
? ? ? ? /// </summary>
? ? ? ? /// <param name="builder">Container builder</param>
? ? ? ? /// <param name="config">Config</param>
? ? ? ? void Register(ContainerBuilder builder,List<Type> listType);
? ? ? ? /// <summary>
? ? ? ? /// Order of this dependency registrar implementation
? ? ? ? /// </summary>
? ? ? ? int Order { get; }
? ? }
public interface IIocManager
? ? {
? ? ? ? IContainer Container { get; }
? ? ? ? bool IsRegistered(Type serviceType, ILifetimeScope scope = null);
? ? ? ? object Resolve(Type type, ILifetimeScope scope = null);
? ? ? ? T Resolve<T>(string key = "", ILifetimeScope scope = null) where T : class;
? ? ? ? T Resolve<T>(params Parameter[] parameters) where T : class;
? ? ? ? T[] ResolveAll<T>(string key = "", ILifetimeScope scope = null);
? ? ? ? object ResolveOptional(Type serviceType, ILifetimeScope scope = null);
? ? ? ? object ResolveUnregistered(Type type, ILifetimeScope scope = null);
? ? ? ? T ResolveUnregistered<T>(ILifetimeScope scope = null) where T : class;
? ? ? ? ILifetimeScope Scope();
? ? ? ? bool TryResolve(Type serviceType, ILifetimeScope scope, out object instance);
? ? }
/// <summary>
? ? /// Container manager
? ? /// </summary>
? ? public class IocManager : IIocManager
? ? {
? ? ? ? private IContainer _container;
? ? ? ? public static IocManager Instance { get { return SingletonInstance; } }
? ? ? ? private static readonly IocManager SingletonInstance = new IocManager();
? ? ? ? /// <summary>
? ? ? ? /// Ioc容器初始化
? ? ? ? /// </summary>
? ? ? ? /// <param name="config"></param>
? ? ? ? /// <returns></returns>
? ? ? ? public IServiceProvider Initialize(IServiceCollection services)
? ? ? ? {
? ? ? ? ? ? var builder = new ContainerBuilder();
? ? ? ? ? ? builder.RegisterInstance(Instance).As<IIocManager>().SingleInstance();
? ? ? ? ? ? //所有程序集 和程序集下類型
? ? ? ? ? ? var deps = DependencyContext.Default;
? ? ? ? ? ? var libs = deps.CompileLibraries.Where(lib => !lib.Serviceable && lib.Type != "package");//排除所有的系統程序集、Nuget下載包
? ? ? ? ? ? var listAllType = new List<Type>();
? ? ? ? ? ? foreach (var lib in libs)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? try
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));
? ? ? ? ? ? ? ? ? ? listAllType.AddRange(assembly.GetTypes().Where(type => type != null));
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? catch { }
? ? ? ? ? ? }
? ? ? ? ? ? //找到所有外部IDependencyRegistrar實現,調用注冊
? ? ? ? ? ? var registrarType = typeof(IDependencyRegistrar);
? ? ? ? ? ? var arrRegistrarType = listAllType.Where(t => registrarType.IsAssignableFrom(t) && t != registrarType).ToArray();
? ? ? ? ? ? var listRegistrarInstances = new List<IDependencyRegistrar>();
? ? ? ? ? ? foreach (var drType in arrRegistrarType)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? listRegistrarInstances.Add((IDependencyRegistrar)Activator.CreateInstance(drType));
? ? ? ? ? ? }
? ? ? ? ? ? //排序
? ? ? ? ? ? listRegistrarInstances = listRegistrarInstances.OrderBy(t => t.Order).ToList();
? ? ? ? ? ? foreach (var dependencyRegistrar in listRegistrarInstances)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? dependencyRegistrar.Register(builder, listAllType);
? ? ? ? ? ? }
? ? ? ? ? ? //注冊ITransientDependency實現類
? ? ? ? ? ? var dependencyType = typeof(ITransientDependency);
? ? ? ? ? ? var arrDependencyType = listAllType.Where(t => dependencyType.IsAssignableFrom(t) && t != dependencyType).ToArray();
? ? ? ? ? ? builder.RegisterTypes(arrDependencyType)
? ? ? ? ? ? ? ? .AsImplementedInterfaces()
? ? ? ? ? ? ? ? .InstancePerLifetimeScope()
? ? ? ? ? ? ? ? .PropertiesAutowired().EnableInterfaceInterceptors();
? ? ? ? ? ? foreach (Type type in arrDependencyType)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (type.IsClass && !type.IsAbstract && !type.BaseType.IsInterface && type.BaseType != typeof(object))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? builder.RegisterType(type).As(type.BaseType)
? ? ? ? ? ? ? ? ? ? ? ? .InstancePerLifetimeScope()
? ? ? ? ? ? ? ? ? ? ? ? .PropertiesAutowired();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? //注冊ISingletonDependency實現類
? ? ? ? ? ? var singletonDependencyType = typeof(ISingletonDependency);
? ? ? ? ? ? var arrSingletonDependencyType = listAllType.Where(t => singletonDependencyType.IsAssignableFrom(t) && t != singletonDependencyType).ToArray();
? ? ? ? ? ? builder.RegisterTypes(arrSingletonDependencyType)
? ? ? ? ? ? ? ? .AsImplementedInterfaces()
? ? ? ? ? ? ? ? .SingleInstance()
? ? ? ? ? ? ? ? .PropertiesAutowired();
? ? ? ? ? ? foreach (Type type in arrSingletonDependencyType)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if (type.IsClass && !type.IsAbstract && !type.BaseType.IsInterface && type.BaseType != typeof(object))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? builder.RegisterType(type).As(type.BaseType)
? ? ? ? ? ? ? ? ? ? ? ? .SingleInstance()
? ? ? ? ? ? ? ? ? ? ? ? .PropertiesAutowired();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? builder.Populate(services);
? ? ? ? ? ? _container = builder.Build();
? ? ? ? ? ? return new AutofacServiceProvider(_container);
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// Gets a container
? ? ? ? /// </summary>
? ? ? ? public virtual IContainer Container
? ? ? ? {
? ? ? ? ? ? get
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return _container;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// Resolve
? ? ? ? /// </summary>
? ? ? ? /// <typeparam name="T">Type</typeparam>
? ? ? ? /// <param name="key">key</param>
? ? ? ? /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>
? ? ? ? /// <returns>Resolved service</returns>
? ? ? ? public virtual T Resolve<T>(string key = "", ILifetimeScope scope = null) where T : class
? ? ? ? {
? ? ? ? ? ? if (scope == null)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //no scope specified
? ? ? ? ? ? ? ? scope = Scope();
? ? ? ? ? ? }
? ? ? ? ? ? if (string.IsNullOrEmpty(key))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return scope.Resolve<T>();
? ? ? ? ? ? }
? ? ? ? ? ? return scope.ResolveKeyed<T>(key);
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// Resolve
? ? ? ? /// </summary>
? ? ? ? /// <typeparam name="T">Type</typeparam>
? ? ? ? /// <param name="key">key</param>
? ? ? ? /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>
? ? ? ? /// <returns>Resolved service</returns>
? ? ? ? public virtual T Resolve<T>(params Parameter[] parameters) where T : class
? ? ? ? {
? ? ? ? ? ? var scope = Scope();
? ? ? ? ? ? return scope.Resolve<T>(parameters);
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// Resolve
? ? ? ? /// </summary>
? ? ? ? /// <param name="type">Type</param>
? ? ? ? /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>
? ? ? ? /// <returns>Resolved service</returns>
? ? ? ? public virtual object Resolve(Type type, ILifetimeScope scope = null)
? ? ? ? {
? ? ? ? ? ? if (scope == null)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //no scope specified
? ? ? ? ? ? ? ? scope = Scope();
? ? ? ? ? ? }
? ? ? ? ? ? return scope.Resolve(type);
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// Resolve all
? ? ? ? /// </summary>
? ? ? ? /// <typeparam name="T">Type</typeparam>
? ? ? ? /// <param name="key">key</param>
? ? ? ? /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>
? ? ? ? /// <returns>Resolved services</returns>
? ? ? ? public virtual T[] ResolveAll<T>(string key = "", ILifetimeScope scope = null)
? ? ? ? {
? ? ? ? ? ? if (scope == null)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //no scope specified
? ? ? ? ? ? ? ? scope = Scope();
? ? ? ? ? ? }
? ? ? ? ? ? if (string.IsNullOrEmpty(key))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return scope.Resolve<IEnumerable<T>>().ToArray();
? ? ? ? ? ? }
? ? ? ? ? ? return scope.ResolveKeyed<IEnumerable<T>>(key).ToArray();
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// Resolve unregistered service
? ? ? ? /// </summary>
? ? ? ? /// <typeparam name="T">Type</typeparam>
? ? ? ? /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>
? ? ? ? /// <returns>Resolved service</returns>
? ? ? ? public virtual T ResolveUnregistered<T>(ILifetimeScope scope = null) where T : class
? ? ? ? {
? ? ? ? ? ? return ResolveUnregistered(typeof(T), scope) as T;
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// Resolve unregistered service
? ? ? ? /// </summary>
? ? ? ? /// <param name="type">Type</param>
? ? ? ? /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>
? ? ? ? /// <returns>Resolved service</returns>
? ? ? ? public virtual object ResolveUnregistered(Type type, ILifetimeScope scope = null)
? ? ? ? {
? ? ? ? ? ? if (scope == null)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //no scope specified
? ? ? ? ? ? ? ? scope = Scope();
? ? ? ? ? ? }
? ? ? ? ? ? var constructors = type.GetConstructors();
? ? ? ? ? ? foreach (var constructor in constructors)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? try
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? var parameters = constructor.GetParameters();
? ? ? ? ? ? ? ? ? ? var parameterInstances = new List<object>();
? ? ? ? ? ? ? ? ? ? foreach (var parameter in parameters)
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? var service = Resolve(parameter.ParameterType, scope);
? ? ? ? ? ? ? ? ? ? ? ? if (service == null) throw new Exception("Unknown dependency");
? ? ? ? ? ? ? ? ? ? ? ? parameterInstances.Add(service);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? return Activator.CreateInstance(type, parameterInstances.ToArray());
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? catch (Exception)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? throw new Exception("No constructor? was found that had all the dependencies satisfied.");
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// Try to resolve srevice
? ? ? ? /// </summary>
? ? ? ? /// <param name="serviceType">Type</param>
? ? ? ? /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>
? ? ? ? /// <param name="instance">Resolved service</param>
? ? ? ? /// <returns>Value indicating whether service has been successfully resolved</returns>
? ? ? ? public virtual bool TryResolve(Type serviceType, ILifetimeScope scope, out object instance)
? ? ? ? {
? ? ? ? ? ? if (scope == null)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //no scope specified
? ? ? ? ? ? ? ? scope = Scope();
? ? ? ? ? ? }
? ? ? ? ? ? return scope.TryResolve(serviceType, out instance);
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// Check whether some service is registered (can be resolved)
? ? ? ? /// </summary>
? ? ? ? /// <param name="serviceType">Type</param>
? ? ? ? /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>
? ? ? ? /// <returns>Result</returns>
? ? ? ? public virtual bool IsRegistered(Type serviceType, ILifetimeScope scope = null)
? ? ? ? {
? ? ? ? ? ? if (scope == null)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //no scope specified
? ? ? ? ? ? ? ? scope = Scope();
? ? ? ? ? ? }
? ? ? ? ? ? return scope.IsRegistered(serviceType);
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// Resolve optional
? ? ? ? /// </summary>
? ? ? ? /// <param name="serviceType">Type</param>
? ? ? ? /// <param name="scope">Scope; pass null to automatically resolve the current scope</param>
? ? ? ? /// <returns>Resolved service</returns>
? ? ? ? public virtual object ResolveOptional(Type serviceType, ILifetimeScope scope = null)
? ? ? ? {
? ? ? ? ? ? if (scope == null)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //no scope specified
? ? ? ? ? ? ? ? scope = Scope();
? ? ? ? ? ? }
? ? ? ? ? ? return scope.ResolveOptional(serviceType);
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? /// Get current scope
? ? ? ? /// </summary>
? ? ? ? /// <returns>Scope</returns>
? ? ? ? public virtual ILifetimeScope Scope()
? ? ? ? {
? ? ? ? ? ? try
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //when such lifetime scope is returned, you should be sure that it'll be disposed once used (e.g. in schedule tasks)
? ? ? ? ? ? ? ? return Container.BeginLifetimeScope();
? ? ? ? ? ? }
? ? ? ? ? ? catch (Exception)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //we can get an exception here if RequestLifetimeScope is already disposed
? ? ? ? ? ? ? ? //for example, requested in or after "Application_EndRequest" handler
? ? ? ? ? ? ? ? //but note that usually it should never happen
? ? ? ? ? ? ? ? //when such lifetime scope is returned, you should be sure that it'll be disposed once used (e.g. in schedule tasks)
? ? ? ? ? ? ? ? return Container.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag);
? ? ? ? ? ? }
? ? ? ? }
? ? }
使用介紹
public IServiceProvider ConfigureServices(IServiceCollection services){services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());services.AddMvc(); ? ? ? ??? ?return IocManager.Instance.Initialize(services);}
特殊場景介紹
通過上面的封裝后,我們可以把Controller的注冊單獨出來
/// <summary>
? ? ///?
? ? /// </summary>
? ? public class ControllerRegistrar : IDependencyRegistrar
? ? {
? ? ? ? /// <summary>
? ? ? ? ///?
? ? ? ? /// </summary>
? ? ? ? public int Order
? ? ? ? {
? ? ? ? ? ? get
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return 0;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? /// <summary>
? ? ? ? ///?
? ? ? ? /// </summary>
? ? ? ? /// <param name="builder"></param>
? ? ? ? /// <param name="listType"></param>
? ? ? ? public void Register(ContainerBuilder builder, List<Type> listType)
? ? ? ? {
? ? ? ? ? ? builder.RegisterType(typeof(LogInterceptor));
? ? ? ? ? ? //注冊Controller,實現屬性注入
? ? ? ? ? ? var IControllerType = typeof(ControllerBase);
? ? ? ? ? ? var arrControllerType = listType.Where(t => IControllerType.IsAssignableFrom(t) && t != IControllerType).ToArray();
? ? ? ? ? ? builder.RegisterTypes(arrControllerType).PropertiesAutowired().EnableClassInterceptors();
? ? ? ? }
? ? }
下面介紹幾種特殊使用方式
1.創建實例時給指定參數賦值
builder.RegisterType(typeof(TestDemo)).AsSelf();
??
public class TestDemo
? ? {
? ? ? ? private readonly string _name;
? ? ? ? private readonly string _sex;
? ? ? ? private readonly int _age;
? ? ? ? public TestDemo(string name, string sex, int age)
? ? ? ? {
? ? ? ? ? ? _name = name;
? ? ? ? ? ? _age = age;
? ? ? ? ? ? _sex = sex;
? ? ? ? }
? ? ? ? public string Sex
? ? ? ? {
? ? ? ? ? ? get
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return _sex;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? public string Name
? ? ? ? {
? ? ? ? ? ? get
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return _name;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? public int Age
? ? ? ? {
? ? ? ? ? ? get
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return _age;
? ? ? ? ? ? }
? ? ? ? }
? ? }
使用示例
var iocManager = app.ApplicationServices.GetService<IIocManager>();
List<Parameter> cparams = new List<Parameter>();
cparams.Add(new NamedParameter("name", "張三"));
cparams.Add(new NamedParameter("sex", "男"));
cparams.Add(new TypedParameter(typeof(int), 2));
var testDemo = iocManager.Resolve<TestDemo>(cparams.ToArray());
Console.WriteLine($"姓名:{testDemo.Name},年齡:{testDemo.Age},性別:{testDemo.Sex}");
?2.對象激活事件
Autofac暴露五個事件接口供實例的按如下順序調用
OnRegistered
OnPreparing
OnActivated
OnActivating
OnRelease
這些事件會在注冊的時候被訂閱,或者被附加到IComponentRegistration 的時候。
builder.RegisterType(typeof(TestDemo)).AsSelf().OnRegistered(e => Console.WriteLine("OnRegistered在注冊的時候調用!")).OnPreparing(e => Console.WriteLine("OnPreparing在準備創建的時候調用!")).OnActivating(e => Console.WriteLine("OnActivating在創建之前調用!")).OnActivated(e => Console.WriteLine("OnActivated創建之后調用!")).OnRelease(e => Console.WriteLine("OnRelease在釋放占用的資源之前調用!"));可以在這些事件里面做些特殊場景處理
總結
? ? ? 本篇介紹了Autofac在項目中的使用方式以及幾種特殊使用場景。其它未介紹知識如生命周期請參考http://autofac.readthedocs.io/en/latest/getting-started/index.html。
相關文章:
ASP.NET Core依賴注入解讀&使用Autofac替代實現
Autofac+Castle實現AOP事務
原文地址:http://www.cnblogs.com/yanweidie/p/autofac.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的.net core2.0下Ioc容器Autofac使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET Core MVC 2.1
- 下一篇: 微软重组变两大事业部:Windows主管