0

Castle Winsdor を DI 解決ツールとして使用しています。

私はエンティティコードをマップします:

container.RegisterServices(
    Assembly.GetAssembly(typeof(GridEntityService<,>))); 

私は2つのジェネリックとのインターフェースを持っています:

IGridEntityService<TEntity,TService>

そして、私はこのインターフェースの 2 つの実装を持っています。初め:

GridEntityService<TEntity,TService>: IGridEntityService<TEntity,TService>

また、カスタム実装もあります。2番:

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

3 に答える 3

3

問題は、Windsor が特定性の低いタイプよりも特定性の高いタイプを選択することです。そのため、コンポーネントとサービスのペアがある場合:

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

2 番目のコンポーネントよりも具体的であるため、デフォルトで最初のコンポーネントが選択されます。

これを適切に処理する方法は、アプリケーションごとに異なります。

このサービスを満足させたくないのに、なぜ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 に答える