dependency-injection - Autofac 如何替换已注册的服务?
问题描述
我想写一个AOP框架(为了学习),我需要替换已经注册在Autofac中的服务。
在Microsoft.Extensions.DependencyInjection中:</p>
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。
然而,最后获胜的概念适用于 Microsoft 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,则内置对装饰器和类型拦截器的支持,这可能会让您的生活更轻松。标准 Microsoft DI 库不提供装饰器和拦截器。
推荐阅读
- python - 我无法从字节中读取带有 open-cv 的图像
- python - 无法导入模块“lambda”:没有名为“paramiko”的模块
- google-apps-script - 如何在 AppScript 中为表单创建上传选项?
- android - 如何在 exoplayer 中播放受 drm 保护的内容?
- angular - 从两个不同的组件添加相同的服务数组中的元素 - 角度
- node.js - Braintree 支付 Apple Pay,支付给 PayPal
- c - gethostbyname 未知主机
- linux - 主偏移值在 ptp4l 中波动的原因可能是什么
- python - flasksaml2idp SAML 注销请求参数
- android - 由于配置更改而重新启动活动