我使用Castle Winsdor作为DI解析工具。
我映射了entites代码:
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
}
我怎么能对温莎城堡说正确的?为什么他们弄错了?我有其他地方,我有类似的服务,他们工作正常。
编辑。 Anwser发表评论。你是对的。它的扩展方法是:
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>()));
}
答案 0 :(得分:3)
问题是,温莎将选择一种更具体的类型,而不是特定类型。这就是为什么,如果你有组件/服务对:
TaskServiceTwo / IGridEntityService<Report, LoginService>
GridEntityService<, > / IGridEntityService<, >
默认情况下会选择第一个组件,因为它比第二个组件更具体。
现在正确的方法,因应用程序而异。
如果您不希望它满足此服务,您为什么会TaskServiceTwo
曝光IGridEntityService<Report, LoginService>
?
也许它的注册应该被修改,或者它根本不应该注册?
如果你想保留它(可能还有一些其他组件依赖它),只需覆盖这个特定情况的默认值......好吧,你可以。
注册UserController
时,您应将其配置为依赖GridEntityService<, >
。 The documentation shows you all the options for doing that
答案 1 :(得分:1)
也许有一种更简单的方法,但据我所知,你必须明确地映射开放泛型类型,如下所示:
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<,>)))
答案 2 :(得分:0)
问题是兑现服务组装。它在bin文件夹中。它需要旧代码,其中没有TaskServiceTwo的实现。我清除了解决方案并手动删除了Service.dll。它修复了问题而不更改代码。