
[英]Autofac 6 - register a decorator as also implementing another interface
[英]DryIoc: register decorator with two interfaces, retrieve the decorator instance when resolving the other interface
这是我试图解决的问题的稍微简化的描述:我有一个服务(例如存储库)实现了一个接口,我需要将其作为依赖项注入:
public class Service: IService {... }
我想添加一个装饰器,例如添加还实现另一个接口的缓存的装饰器:
public class CachingService: IService, IFlushable
{
public CachingService(IService decoratee) { ... }
public void Flush() { ... }
}
public interface IFlushable
{
public void Flush();
}
通常,我只是使用Setup.Decorator
或Setup.DecoratorWith
将 CachingService 注册为 IService 的实现作为装饰器。 但在这种情况下,我有一个与 IFlushable 接口相关的额外要求。 将有几个不同的服务有自己的装饰器,它们都实现了装饰服务接口和 IFlushable。 我需要将所有 IFlushable 装饰器作为依赖项注入,以便能够根据请求刷新所有缓存。
public class CacheHandler
{
public CacheHandler(IFlushable[] cache) { ... }
public void FlushAllCaches() { ... }
}
问题在于此 CacheHandler 必须接收应用于服务类的相同装饰器实例。
我尝试了几种使用RegisterMapping
的解决方案,并尝试将缓存的分辨率 scope 解析为其装饰服务,但我无法使其工作。 我收到容器无法解析装饰器的错误(这是有道理的),或者我需要自己注册装饰器,但在后一种情况下,CacheHandler 将收到一组新的 IFlushable 实例。
我越想越觉得我在这里试图实现的目标甚至可能无法使用 DI 容器。 我的意思是也许我以错误的方式解决了这个问题。 我的问题是我的方法是否有效和/或如何将所有已应用的 IFLushable 装饰器实例作为依赖项获取。
首先,我同意@Steven考虑反转控制并将IFlushable
注入CachingService
。
其次,您可能会以不同的方式实现IService
的装饰器——无需在CachingService
中实现它:
[Test]
public void Answer()
{
var c = new Container();
c.Register<IService, Service>(Reuse.Singleton);
c.RegisterMany<CachingService>(Reuse.Singleton); // registers both CashingService and IFlushable with the same implementing instance
c.RegisterDelegate<CachingService, IService>(cs => cs.GetDecoratedService(), setup: Setup.Decorator);
var s = c.Resolve<IService>();
Assert.IsNotNull(s);
var cs = c.Resolve<CachingService>();
Assert.IsTrue(cs.ServiceDecorated); // check the service indeed is decorated
var f = c.Resolve<IFlushable>();
Assert.AreSame(cs, f); // check that the flushable and caching service are the same instance
}
public interface IService { }
public class Service : IService { }
// no need to implement IService for the decorator, we may use its method instead
public class CachingService : IFlushable
{
public readonly IService Service;
public bool ServiceDecorated;
public CachingService(IService service) => Service = service;
public IService GetDecoratedService()
{
ServiceDecorated = true; // do something with decorated service
return Service;
}
public void Flush() { }
}
public interface IFlushable
{
public void Flush();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.