日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

.net core2.0下Ioc容器Autofac使用

發(fā)布時間:2023/12/4 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .net core2.0下Ioc容器Autofac使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Autofac基本使用

  Autofac是一款輕量級的IOC框架,使用率上還是挺高的,官方網(wǎng)站http://autofac.org,源碼下載地址https://github.com/autofac/Autofac。

  下面以狗的列子來介紹autofac,nuget搜索Autofac進(jìn)行安裝

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實現(xiàn)

? ? 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(讓具體實現(xiàn)類型,可以該類型繼承的所有接口類型找到該實現(xiàn)類型)

  3.RegisterInstance

TibetanMastiff d = new TibetanMastiff(); builder.RegisterInstance(d).As<IDog>();

  4.RegisterModule

  這種模式需要使用配置文件進(jìn)行注冊,個人更喜歡代碼直接注冊的方式,畢竟配置文件修改容易遺忘和出錯。這里就不介紹該方式了。?

? ? ??

  遺留問題:上面的注冊代碼,自己寫寫demo的時候沒啥問題。但是運用到項目里面就很繁瑣了,需要自己一個個類型注冊,后面會提供解決方案。

?

.net core MVC與Autofac

  1.首先nuget下載AutofacAutofac.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默認(rèn)是構(gòu)造函數(shù)注入

[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怎么實現(xiàn)屬性注入呢?

1.注冊系統(tǒng)所有Controller,由Autofac創(chuàng)建

var IControllerType = typeof(ControllerBase); builder.RegisterAssemblyTypes(assembly).Where(t => IControllerType.IsAssignableFrom(t) && t != IControllerType).PropertiesAutowired();

?上面這段代碼的解釋:注冊所有程序集下繼承ControllerBase的類型,PropertiesAutowired 允許屬性注入。

2.替換系統(tǒng)默認(rèn)Controller創(chuàng)建器

services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());services.AddMvc();

注意:Replace代碼放在AddMvc之前

Replace代碼的意思:使用ServiceBasedControllerActivator替換DefaultControllerActivator(意味著框架現(xiàn)在會嘗試從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實現(xiàn)屬性注入

Autofac+Castle實現(xiàn)AOP

1.首先nuget下載Autofac.Extras.DynamicProxy引用

2.編寫攔截器


public class LogInterceptor : IInterceptor

{

? ? public void Intercept(IInvocation invocation)

? ? {

? ? ? ? Console.WriteLine("你正在調(diào)用方法 \"{0}\"? 參數(shù)是 {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("方法執(zhí)行完畢,返回結(jié)果:{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 { }

這種使用方式需要自己指定在哪個類上使用,還有一種全局?jǐn)r截器

builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces().EnableInterfaceInterceptors()
? ?.InterceptedBy(
typeof(LogInterceptor));

?


代碼封裝簡單使用

先列出使用過程中遇到的幾個問題,然后再給出解決方案

1:如何簡單注冊代碼里面的所有類型

2.如何注冊單例和普通對象

3.封裝好的代碼怎么支持用戶特殊化注冊需求

為了解決上述問題,這里給出了幾個約束

單例對象需繼承的接口:ISingletonDependency? 普通對象需繼承的接口:ITransientDependency 特殊化注冊接口:IDependencyRegistrar

通過這幾個約束,在初始化時找所有程序集 繼承ISingletonDependency ,ITransientDependency 接口的對象進(jìn)行類型注冊

/// <summary>/// 單例接口 ? ?/// </summary>public interface ISingletonDependency{}

/// <summary>

? ? /// 所有接口的依賴接口,每次創(chuàng)建新實例

? ? /// </summary>

? ? /// <remarks>

? ? /// 用于Autofac自動注冊時,查找所有依賴該接口的實現(xiàn)。

? ? /// 實現(xiàn)自動注冊功能

? ? /// </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");//排除所有的系統(tǒng)程序集、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實現(xiàn),調(diào)用注冊

? ? ? ? ? ? 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實現(xiàn)類

? ? ? ? ? ? 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實現(xiàn)類

? ? ? ? ? ? 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,實現(xiàn)屬性注入

? ? ? ? ? ? var IControllerType = typeof(ControllerBase);

? ? ? ? ? ? var arrControllerType = listType.Where(t => IControllerType.IsAssignableFrom(t) && t != IControllerType).ToArray();

? ? ? ? ? ? builder.RegisterTypes(arrControllerType).PropertiesAutowired().EnableClassInterceptors();

? ? ? ? }

? ? }

下面介紹幾種特殊使用方式

1.創(chuàng)建實例時給指定參數(shù)賦值

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暴露五個事件接口供實例的按如下順序調(diào)用

  • OnRegistered

  • OnPreparing

  • OnActivated

  • OnActivating

  • OnRelease

  •  這些事件會在注冊的時候被訂閱,或者被附加到IComponentRegistration 的時候。

    builder.RegisterType(typeof(TestDemo)).AsSelf().OnRegistered(e => Console.WriteLine("OnRegistered在注冊的時候調(diào)用!")).OnPreparing(e => Console.WriteLine("OnPreparing在準(zhǔn)備創(chuàng)建的時候調(diào)用!")).OnActivating(e => Console.WriteLine("OnActivating在創(chuàng)建之前調(diào)用!")).OnActivated(e => Console.WriteLine("OnActivated創(chuàng)建之后調(diào)用!")).OnRelease(e => Console.WriteLine("OnRelease在釋放占用的資源之前調(diào)用!"));

    可以在這些事件里面做些特殊場景處理

    總結(jié)

    ? ? ? 本篇介紹了Autofac在項目中的使用方式以及幾種特殊使用場景。其它未介紹知識如生命周期請參考http://autofac.readthedocs.io/en/latest/getting-started/index.html。

    相關(guān)文章:

    • ASP.NET Core依賴注入解讀&使用Autofac替代實現(xiàn)

    • Autofac+Castle實現(xiàn)AOP事務(wù)

    原文地址:http://www.cnblogs.com/yanweidie/p/autofac.html


    .NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com

    總結(jié)

    以上是生活随笔為你收集整理的.net core2.0下Ioc容器Autofac使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。