我想写一个AOP框架(为了学习),我需要替换已经在Autofac注册的服务。
在 Microsoft.Extensions.DependencyInjection(依赖注入):
public static IServiceCollection BuildAopProxy(this IServiceCollection service)
{
if (service is null)
throw new ArgumentNullException(nameof(service));
IServiceCollection proxyServiceCollection = new ServiceCollection();
foreach (ServiceDescriptor item in service)
{
Type newType;
Type serviceType = item.ServiceType;
Type implementationType = item.ImplementationType;
if (serviceType == implementationType)
{
newType = DynamicProxy.CreateProxyClassType(item.ImplementationType, true);
}
else
{
newType = DynamicProxy.CreateProxyClassType(item.ServiceType, item.ImplementationType, false);
}
proxyServiceCollection.Add(ServiceDescriptor.Describe(serviceType, newType, item.Lifetime));
}
return proxyServiceCollection;
}
在Autofac中如何操作?谢谢。
都是关于注册顺序的。在文档中,有一节是关于这个问题的。
基本上是这样的。最后加入的人获胜
首先,需要注意的是,你在例子中使用的是Microsoft.Extensions.DependencyInjection库。这些都不是Autofac。Autofac 可以 整合 随之但你设置你的注册的方式,使用的是 IServiceCollection
不是Autofac。
然而,这个概念 垫底 适用于微软DI和Autofac......以及几乎所有其他DI容器。
如果我注册了三个实现相同接口的东西... ...
svcCollection.AddTransient<IDependency, First>();
svcCollection.AddTransient<IDependency, Second>();
svcCollection.AddTransient<IDependency, Third>();
如果你解决 IDependency
你会得到 Third
:
var provider = svcCollection.BuildServiceProvider();
var dependency = provider.GetService<IDependency>();
// dependency.GetType() == typeof(Third)
如果你真的想在这里使用Autofac,你需要使用Autofac.Extensions.DependencyInjection把所有的注册放到Autofac中。
var builder = new ContainerBuilder();
builder.Populate(svcCollection);
var container = builder.Build();
var dependency = container.Resolve<IDependency>();
// dependency.GetType() == typeof(Third)
或者你可以直接切换到使用原生的Autofac注册。
var builder = new ContainerBuilder();
builder.RegisterType<First>().As<IDependency>();
builder.RegisterType<Second>().As<IDependency>();
builder.RegisterType<Third>().As<IDependency>();
var container = builder.Build();
var dependency = container.Resolve<IDependency>();
// dependency.GetType() == typeof(Third)
看来你所做的部分工作是试图将一些组件包裹在装饰器或代理中。如果你使用原生的Autofac,那么就有 内置支持装饰者 和 拦路虎 这可能会让你的生活更轻松。标准的微软DI库不提供装饰器和拦截器。