C# 在ASP.NET内核的控制器中注入接口的特定实现
我正在开发一个基于ASP.NET内核的web应用程序,并使用Autofac进行依赖项注入 我有一个接口作为C# 在ASP.NET内核的控制器中注入接口的特定实现,c#,asp.net-core,autofac,C#,Asp.net Core,Autofac,我正在开发一个基于ASP.NET内核的web应用程序,并使用Autofac进行依赖项注入 我有一个接口作为ICacheProvider,这个接口有3个具体实现-OrderCacheProvider、ProductsCacheProvider和CustomerCacheProvider。对于不同的缓存提供程序,基础结构和逻辑是不同的。他们的注册情况如下: builder.RegisterType<CustomerCacheProvider>() .Keyed&l
ICacheProvider
,这个接口有3个具体实现-OrderCacheProvider
、ProductsCacheProvider
和CustomerCacheProvider
。对于不同的缓存提供程序,基础结构和逻辑是不同的。他们的注册情况如下:
builder.RegisterType<CustomerCacheProvider>()
.Keyed<ICacheProvider>(CacheType.Customer);
builder.RegisterType<OrderCacheProvider>()
.Keyed<ICacheProvider>(CacheType.Order);
builder.RegisterType<ProductCacheProvider>()
.Keyed<ICacheProvider>(CacheType.Product);
现在我的问题是如何在
OrdersController
中插入orderscacheprovider
?这同样适用于CustomerCacheProvider
到CustomerController
和ProductsCacheProvider
?在注册控制器时,您可以使用with parameter
方法来指定应使用的ICacheProvider
builder.RegisterType<OrdersController>()
.WithParameter(ResolvedParameter.ForKeyed<ICacheProvider>(CacheType.Order));
我更喜欢第一个解决方案,而不是这个看起来更纯粹的解决方案,您的组件只需请求ICacheProvider
就可以了
另一个解决方案是创建一个自定义模块,该模块将根据约定为每个控制器添加参数
protected override void AttachToComponentRegistration(
IComponentRegistry componentRegistry, IComponentRegistration registration)
{
base.AttachToComponentRegistration(componentRegistry, registration);
if (registration.Activator.LimitType.IsSubclassOf(typeof(BaseController)))
{
String controllerName = registration.Activator.LimitType.Name;
controllerName = controllerName.Substring(0, controllerName.Length - 10);
if (Enum.TryParse<CacheType>(controllerName, out CacheType cacheType))
{
registration.Preparing += (sender, e) =>
{
e.Parameters = new Parameter[]
{
ResolvedParameter.ForKeyed<ICacheProvider>(cacheType)
}
.Concat(e.Parameters);
};
}
else
{
// throw, use default cache, do nothing, etc.
throw new Exception($"No cache found for controller {controllerName}");
}
}
}
}
public class OrdersController
{
public OrdersController([KeyFilter(CacheType.Order)]ICacheProvider cacheProvider)
{ }
}
protected override void AttachToComponentRegistration(
IComponentRegistry componentRegistry, IComponentRegistration registration)
{
base.AttachToComponentRegistration(componentRegistry, registration);
if (registration.Activator.LimitType.IsSubclassOf(typeof(BaseController)))
{
String controllerName = registration.Activator.LimitType.Name;
controllerName = controllerName.Substring(0, controllerName.Length - 10);
if (Enum.TryParse<CacheType>(controllerName, out CacheType cacheType))
{
registration.Preparing += (sender, e) =>
{
e.Parameters = new Parameter[]
{
ResolvedParameter.ForKeyed<ICacheProvider>(cacheType)
}
.Concat(e.Parameters);
};
}
else
{
// throw, use default cache, do nothing, etc.
throw new Exception($"No cache found for controller {controllerName}");
}
}
}
}
builder.RegisterModule<CacheProviderModule>();