簡體   English   中英

如何配置Autofac以解析CQRS處理程序並在Web API項目中編寫其查詢調度程序

[英]How to configure Autofac to resolve CQRS handlers and write its query dispatcher in a Web API project

我在Project1的 QUERY端有以下內容,主要包含接口

public interface IQueryResult {}
public interface IQuery<TResult> where TResult : IQueryResult {}
public interface IQueryHandler<TQuery, TResult> 
    where TQuery : IQuery<TResult> 
    where TResult : IQueryResult
{
    Task<TResult> HandleAsync(TQuery query);
}

public class PersonQueryResult : IQueryResult
{
    public string Name { get; set; }
}
public class GetPersonDetailsQuery : IQuery<PersonQueryResult>
{
    public int Id { get; set; }
}
public interface IQueryDispatcher
{
    Task<TResult> DispatchAsync<TQuery, TResult>(TQuery query)
        where TQuery : IQuery<TResult>
        where TResult : IQueryResult;
}

在第二Project2的引用哪個項目1,我有

public class GetPersonDetailsQueryHandler : 
IQueryHandler<GetPersonDetailsQuery, PersonQueryResult>
{
    public Task<PersonQueryResult> HandleAsync(GetPersonDetailsQuery query)
    {
        return Task.FromResult( new PersonQueryResult {Name = "Bamboo"});
    }
}

最后一個Project 3是一個Web API項目,它只引用Project 1但不引用項目2.因此它只知道接口和命令和查詢。 我需要以一種我可以輕松做到這樣的方式來配置autofac

var query = new GetPersonDetailsQuery { Id = 1 };
var magicHappensHere = new QueryDispatcher(); //any better way?
PersonQueryResult result = magicHappensHere.Dispatch(query); 

我在Project 1中擁有的IQueryDispatcher似乎不適合上面的工作。 該接口的示例實現是開放的建議

public class QueryDispatcher : IQueryDispatcher
{
    private readonly IComponentContext _context;

    public QueryDispatcher(IComponentContext context)
    {
        this._context = context;
    }

    public Task<TResult> DispatchAsync<TQuery, TResult>(TQuery query) where TQuery : IQuery<TResult> where TResult : IQueryResult
    {
        var handler = _context.Resolve<IQueryHandler<TQuery, TResult>>();

        return handler.HandleAsync(query);
    }
}

我不知道如何實現的可能解決方案(A)在項目2中定義Autofac模塊,然后在Web API中掃描Project 2程序集?(B) http://docs.autofac.org/en/latest/register /registration.html#open-generic-components(C )掃描程序集並嘗試自動映射。 需要有關插入代碼的幫助

private static void ConfigureAutofac(HttpConfiguration config) 
{
    var builder = new ContainerBuilder();
    //*************//
    //what to do here?
    //**************//
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    builder.RegisterWebApiFilterProvider(config);

    var container = builder.Build();
    config.DependencyResolver = new   AutofacWebApiDependencyResolver(container);
}    

最后得到了建議的解決方案(B) http://docs.autofac.org/en/latest/register/registration.html#open-generic-components來工作。 此外,我可以確認解決方案中沒有添加對dll的引用

但是我仍然需要一種很好的方法來從API項目中調度查詢。 更直觀的東西

private static void ConfigureAutofac(HttpConfiguration config) 
{
    var builder = new ContainerBuilder();
    //*************//
    //heres what i did
    //*************//
    var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>();

    foreach (var assembly in assemblies)
    {
        builder.RegisterAssemblyTypes(assembly).AssignableTo<IQueryResult>().AsImplementedInterfaces();

        builder.RegisterAssemblyTypes(assembly).AsClosedTypesOf(typeof(IQuery<>)).AsImplementedInterfaces();

        builder.RegisterAssemblyTypes(assembly).AsClosedTypesOf(typeof(IQueryHandler<,>)).AsImplementedInterfaces();

    } 
    //rest of the code
}   

您的Web API項目包含應用程序的組合根 ,組合根按定義引用應用程序中的所有其他程序集。 沒有引用它是沒有意義的,只是使事情復雜化。

請閱讀此q / a以獲得更詳細的討論:

許多開發人員不希望他們的[Web API]程序集依賴於DAL程序集,但這不是一個真正的問題。 不要忘記程序集是部署工件; 您將代碼拆分為多個程序集,以允許單獨部署代碼。 另一方面,架構層是邏輯工件。 在同一個程序集中擁有多個層是非常可能的(也是常見的)。 在這種情況下,我們最終會在同一個Web應用程序項目中具有組合根(層)和表示層(因此在同一個程序集中)。 即使該程序集引用包含DAL的程序集,表示層仍然不引用數據訪問層。 這是一個很大的區別。 當然,當我們這樣做時,我們失去了編譯器在編譯時檢查這個架構規則的能力,但這應該不是問題。 大多數架構規則實際上都不能由編譯器檢查,並且總是有類似常識的東西。 如果您的團隊中沒有常識,您可以隨時使用代碼審查(每個團隊都應該IMO總是這樣做)。 您還可以使用NDepend(商業版)等工具,它可以幫助您驗證架構規則。

通常,只有在具有插件模型的情況下,才能防止從組合根到其他程序集的硬引用,其中程序集在編譯時是未知的,並且可以在部署期間或之后添加。 然而,這些類型的場景對於LOB應用程序來說並不常見。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM