我们将IQueryHandler<TQUery,TResult>
注入我们的MVC控制器。我们在容器中全局注册所有这些
我们编写了一个可以缓存IQueryHandler
。
我们希望有时得到缓存的结果,而有时则不是来自同一个处理程序。
是否可以根据构造函数参数的名称有条件地获取修饰处理程序。例如注入IQueryHandler<UnemployedQuery, IEnumerable<People>> cachedPeopleHandler
如果我们在构造函数参数名称前加上缓存,我们实际上是用decorator包装的吗?
尝试使用更多约定优于配置方法来简化操作。
答案 0 :(得分:2)
是的,可以这样做。下面是一个简单的工作示例,说明如何实现它:
class Program
{
public interface IQueryHandler{}
private class QueryHandler : IQueryHandler
{
}
private class CacheQueryHandler : IQueryHandler
{
}
public interface IService
{
}
private class Service : IService
{
private readonly IQueryHandler _queryHandler;
private readonly IQueryHandler _cacheQueryHandler;
public Service(IQueryHandler queryHandler, IQueryHandler cacheQueryHandler)
{
_queryHandler = queryHandler;
_cacheQueryHandler = cacheQueryHandler;
}
public override string ToString()
{
return string.Format("_queryHandler is {0}; _cacheQueryHandler is {1}", _queryHandler,
_cacheQueryHandler);
}
}
static void Main(string[] args)
{
var builder = new ContainerBuilder();
// Register the dependency
builder.RegisterType<QueryHandler>().As<IQueryHandler>();
// Register the decorator of the dependency
builder.RegisterType<CacheQueryHandler>().Keyed<IQueryHandler>("cache");
// Register the service implementation
builder.RegisterType<Service>().AsSelf();
// Register the interface of the service
builder.Register(c =>
{
var ctor = typeof (Service).GetConstructors()[0];
var parameters =
ctor.GetParameters()
.Where(p => p.Name.StartsWith("cache"))
.Select(p => new NamedParameter(p.Name, c.ResolveKeyed("cache", p.ParameterType)));
return c.Resolve<Service>(parameters);
}).As<IService>();
using (var container = builder.Build())
{
var service = container.Resolve<IService>();
Console.WriteLine(service.ToString());
Console.ReadKey();
}
}
}
<强>更新强>
基本上你需要:
1.想一个大会。在您的情况下为ctor参数名称添加“缓存”
2.像往常一样注册您的依赖项
3.注册装饰器,这样它们就不会覆盖原始依赖项,您可以根据惯例轻松解决它们。例如键控,命名,通过属性等。
注册你使用装饰器的类的实际实现
5.通过内部具有所有魔法的lambda表达式注册描述该类的接口。
注意:我提供了一个简单而有效的例子。让它变得美观,易于使用和快速,例如将它作为扩展,通用,缓存反射结果等。无论如何,这并不困难 感谢。