2011-11-02 9 views
4

実行時にそれ自体を解決するジェネリックデリゲートを登録したいのですが、ジェネリックでこれを行う方法が見つかりません。オープンなジェネリックデリゲートをautofacに登録することはできますか?

public delegate TOutput Pipe<in TInput, out TOutput>(TInput input); 

そして、このようになり、離散的に登録されたデリゲート与えられた:私はこの線に沿って機能を登録する

public class AnonymousPipe<TInput, TOutput> 
{ 
    public Pipe<TInput, TOutput> GetPipe(IContext context) 
    {...} 

を:

次のようになりますデリゲートを考える

builder.RegisterGeneric(typeof(Pipe<,>)).As(ctx => 
{ 
    var typeArray = ctx.RequestedType.GetGenericArguments(); 
    // this can be memoized 
    var pipeDefinition = ctx.Resolve(typeof(AnonymousPipe<,>).MakeGenericType(typeArray)); 

    return pipeDefinition.GetPipe(ctx); 

ジェネリックの実装をparameとして提供する方法が見つかりませんAutofacのter - 私は何かが欠けているかもしれません。私は一般的なオブジェクトやインターフェイスを通してこれを行うことができますが、私はデリゲートの軽さにこだわりたいと思います。ユニットテストは、これらの注入に非常に簡単です。

どのような考えですか?私は現時点で個別の登録をしなければなりません(タイプの組み合わせごとに1つ、ジェネリックはありません)。

私は登録のみソースソリューションを考え出すことができる
+0

Wow Steve、このような挑戦を設定することを信頼してください:) :) Hmmmmmmmmmm thインキング思考... –

答えて

4

class PipeSource : IRegistrationSource 
{ 
    public bool IsAdapterForIndividualComponents { get { return true; } } 

    public IEnumerable<IComponentRegistration> RegistrationsFor(
     Service service, 
     Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor) 
    { 
     var swt = service as IServiceWithType; 
     if (swt == null || !swt.ServiceType.IsGenericType) 
      yield break; 

     var def = swt.ServiceType.GetGenericTypeDefinition(); 
     if (def != typeof(Pipe<,>)) 
      yield break; 

     var anonPipeService = swt.ChangeType(
      typeof(AnonymousPipe<,>).MakeGenericType(
       swt.ServiceType.GetGenericArguments())); 

     var getPipeMethod = anonPipeService.ServiceType.GetMethod("GetPipe"); 

     foreach (var anonPipeReg in registrationAccessor(anonPipeService)) 
     { 
      yield return RegistrationBuilder.ForDelegate((c, p) => { 
        var anon = c.ResolveComponent(anonPipeReg, p); 
        return getPipeMethod.Invoke(anon, null); }) 
       .As(service) 
       .Targeting(anonPipeReg) 
       .CreateRegistration(); 
     } 
    } 
} 

その後(Autofacユニバーサルハンマー。):今

builder.RegisterSource(new PipeSource()); 

、私は「は私ができる特定よWebページにコードを入れて実際にコンパイルして実行させますが、それは近いかもしれません:)

+0

ありがとうニック!コードは、私が必要とすることの心臓部に私を連れて行きます。コンパイルしたコードをすぐに投稿します。 –

関連する問題