Castle Winsdor自动解析通用接口工作不正确
本文关键字:接口 工作 不正确 Winsdor Castle | 更新日期: 2023-09-27 18:11:28
我使用Castle windsor作为DI解析工具。
I映射实体代码:
container.RegisterServices(
Assembly.GetAssembly(typeof(GridEntityService<,>)));
我有两个泛型接口:
IGridEntityService<TEntity,TService>
我有这个接口的两个实现。第一:
GridEntityService<TEntity,TService>: IGridEntityService<TEntity,TService>
我还有自定义实现。第二:
TaskServiceOne : GridEntityService<User, LoginService> { }
TaskServiceTwo : GridEntityService<Report, LoginService> { }
在我的控制器构造函数:
public UserController(
IGridEntityService<User, LoginService> userService,
IGridEntityService<Report, LoginService> reportService)
{
// Get Correct one TaskServiceOne
GridEntityService = userService;
// Get GridEntityService<Report, LoginService>
// not the TaskServiceTwo
GridSecondEntityService = reportService
}
我怎么说温莎城堡得到正确的一个?为什么会出错呢?我在其他地方也有类似的服务,而且运行得很好。
编辑。回复评论。你说得对。它的扩展方法:
public static void RegisterServices(this IWindsorContainer container, Assembly assembly)
{
container.Register(
AllTypes.FromAssembly(assembly).Where(t => true).WithService.AllInterfaces().Configure(
reg => reg.LifeStyle.Custom<InstantiateAndForgetIt>()));
}
问题是,Windsor会选择更具体的类型,而不是不太具体的类型。这就是为什么,如果你有组件/服务对:
TaskServiceTwo / IGridEntityService<Report, LoginService>
GridEntityService<, > / IGridEntityService<, >
它将默认选择第一个组件,因为它比第二个组件更具体。
正确的方法是不同的应用程序
如果您不希望它满足此服务,为什么您甚至让TaskServiceTwo
暴露IGridEntityService<Report, LoginService>
?
也许它的注册应该改变,或者根本不应该注册?
如果你想保留它(也许其他一些组件依赖于它),只需覆盖这个特定情况的默认值…好吧,你可以。
注册UserController
时,您应该将其配置为依赖于GridEntityService<, >
。文档向您展示了执行此操作的所有选项。
也许有更简单的方法,但据我所知,您必须显式地映射开放泛型类型,如下所示:
container.Register(AllTypes.From(
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetExportedTypes()))
.BasedOn(typeof(IGridEntityService<,>))
.Unless(t => t.IsGenericTypeDefinition)
.WithService.Select((_, baseTypes) =>
{
return
from t in baseTypes
where t.IsGenericType
let td = t.GetGenericTypeDefinition()
where td == typeof(IGridEntityService<,>)
select t;
})
.Configure(c => c.LifeStyle.Transient));
container.Register(Component
.For(typeof(IGridEntityService<,>))
.ImplementedBy(typeof(GridEntityService<,>)))
问题是兑现服务程序集。它在bin文件夹里。它使用旧代码,其中没有实现TaskServiceTwo。我清除了解决方案并手动删除了Service.dll。它在不更改代码的情况下修复了这个问题。