[英]How to register an autofac decorator for a generic object for CQRS
是CQRS的實現:
public interface IQuery<TResult> {}
public interface IQueryHandler<in TQuery, TResult>
where TQuery : IQuery<TResult>
{
Task<TResult> HandleAsync(TQuery query);
}
public interface IQueryDispatcher
{
Task<TResult> DispatchAsync<TQuery, TResult>(TQuery query)
where TQuery : IQuery<TResult>;
}
public class QueryDispatcher : IQueryDispatcher
{
private readonly IComponentContext resolver;
public QueryDispatcher(IComponentContext resolver)
{
if (resolver == null)
{
throw new ArgumentNullException(nameof(resolver));
}
this.resolver = resolver;
}
public async Task<TResult> DispatchAsync<TQuery, TResult>(TQuery query)
where TQuery : IQuery<TResult>
{
if (query == null)
{
throw new ArgumentNullException(nameof(query));
}
var handler = resolver.Resolve<IQueryHandler<TQuery, TResult>>();
return await handler.HandleAsync(query);
}
}
我想創建通用查詢:
public class GetEntitiesQuery<TEntity> : IQuery<IQueryable<TEntity>>
where TEntity : Entity
{
}
public class GetEntitiesQueryHandler<TEntity> : IQueryHandler<GetEntitiesQuery<TEntity>, IQueryable<TEntity>>
where TEntity : Entity
{
// this code ...
}
我正在嘗試注冊一個通用類,如下所示:
builder.RegisterType<QueryDispatcher>().As<IQueryDispatcher>().InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(assemblies)
.As(type => type.GetInterfaces()
.Where(interfaceType => interfaceType.IsClosedTypeOf(typeof(IQueryHandler<,>)))
.Select(interfaceType => new KeyedService("QueryHandler", interfaceType)))
.InstancePerLifetimeScope();
並拋出錯誤IQueryHandler尚未注冊
Autofac有可能嗎?
與在ASP.NET Core中使用Autofac注冊通用類型的問題有很多共同點
您顯示的代碼中沒有裝飾器。
通過使用KeyedService
類鍵入處理程序的鍵來注冊處理程序時,會KeyedService
。 如果您想讓代碼正常工作,則有兩種解決方案。
最好的選擇是不對服務進行加密,因為沒有理由-只需查看包含的代碼即可對服務進行加密。 您可以注冊它們而無需通過以下方式鍵入它們:
builder
.RegisterAssemblyTypes(assemblies)
.AsClosedTypesOf(typeof(IQueryHandler<,>))
.InstancePerLifetimeScope();
另一種選擇是在解析IQueryHandler<TQuery, TResult>
時指示Autofac您正在尋找鍵服務IQueryHandler<TQuery, TResult>
因為這是您注冊它們的方式。 為此,您必須將QueryDispatcher
代碼修改為:
var handler = resolver.ResolveKeyed<IQueryHandler<TQuery, TResult>>("QueryHandler");
請不要將傳遞給ResolveKeyed
方法的密鑰與ResolveKeyed
中使用的密鑰匹配。 我不知道為什么您會選擇第二個選項,但是有可能。
我認為您對裝飾家有些困惑。 使用它們需要您對服務進行密鑰設置,以便您可以裝飾已被密鑰化的服務。 請再看一下相關文檔 。
Edwok發表評論后進行編輯
對於通用的GetEntitiesQueryHandler<TEntity>
案例,我想說您必須將其注冊為開放式通用組件 :
builder
.RegisterGeneric(typeof(GenericEntitiesQueryHandler<>))
.As(typeof(IQueryHandler<,>));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.