0

我使用 Castle Winsdor 作为 DI 解析工具。

我映射实体代码:

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>()));
            }
4

3 回答 3

3

问题是,温莎会选择更具体的类型,而不是不太具体的类型。这就是为什么,如果您有组件/服务对:

TaskServiceTwo / IGridEntityService<Report, LoginService>
GridEntityService<, > / IGridEntityService<, >

它会默认选择第一个组件,因为它比第二个更具体。

现在,正确的方法因应用程序而异。

如果您不希望它满足这项服务,为什么还要TaskServiceTwo曝光?IGridEntityService<Report, LoginService>

也许它的注册应该改变,或者根本不应该注册?

如果您确实想保留它(也许其他一些组件依赖它)并且只是覆盖这个特定情况的默认值......好吧,您可以。

注册时,UserController您应该将其配置为依赖于GridEntityService<, >. 该文档向您展示了执行此操作的所有选项

于 2013-05-01T01:04:55.083 回答
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<,>)))
于 2013-04-30T17:17:43.490 回答
0

问题是兑现服务大会。它在 bin 文件夹中。它采用旧代码,其中没有 TaskServiceTwo 的实现。我清除了解决方案并手动删除了 Service.dll。它在不更改代码的情况下解决了问题。

于 2013-05-02T10:26:24.620 回答