我在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;
}
在引用项目1的第二个Project2中,我有
public class GetPersonDetailsQueryHandler :
IQueryHandler<GetPersonDetailsQuery, PersonQueryResult>
{
public Task<PersonQueryResult> HandleAsync(GetPersonDetailsQuery query)
{
return Task.FromResult( new PersonQueryResult {Name = "Bamboo"});
}
}
最后一个项目3是一个Web API项目,该项目仅引用项目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)在Project 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
}