2011-08-08 21 views
1

この問題をどのように述べるかわからない、問題がどこにあるのかわからない。私はその遺伝的共分散問題だと思うが、その解決策は、おそらくインターフェースが設計されている方法や、実装の登録方法にあるかもしれない。Autofac登録し、一般的なインターアートを実装するタイプを解決する

とにかく、サンプルは汎用インターフェースを実装するすべてのタイプを登録しようとしており、後で汎用タイプのタイプを使用してタイプを解決しようとしています。次に、この型をその基本型にキャストしようとすると、その実装上でメソッドを呼び出すことができます。

キャストしようとすると失敗します。例として、コードの最初の行はコンパイルに失敗します。削除すると、実装をキャストしようとしている行でプログラムが失敗します。

class Program 
{ 
    private static IContainer _container; 

    static void Main(string[] args) 
    { 
     // Is this the problem? 
     IHandler<IConfiguration> test = new MyHandler(); 

     // setup ioc 
     var builder = new ContainerBuilder(); 
     builder.RegisterAssemblyTypes(typeof(Program).Assembly) 
      //.Where(t => typeof(IHandler<IConfiguration>).IsAssignableFrom(t)); 
      .Where(t => t.GetInterfaces() 
       .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IHandler<>)) 
       .Any() 
       ) 
      .As(t => t.GetInterfaces() 
       .Where(i => i.GetGenericTypeDefinition() == typeof(IHandler<>)) 
       .Single() 
      ); 
     _container = builder.Build(); 

     // get my configuration impl 
     var configuration = new MyConfiguration(); 

     // resolve handler for the configuration 
     var configurationType = configuration.GetType(); 
     var handlerGenericType = typeof(IHandler<>); 
     var handlerType = handlerGenericType.MakeGenericType(configurationType); 
     var handler = _container.Resolve(handlerType); 
     var typedHandler = (IHandler<IConfiguration>) handler; 

     // handle it! 
     typedHandler.Handle(configuration); 
    } 
} 

public interface IConfiguration 
{ 
} 

public interface IHandler<T> where T : IConfiguration 
{ 
    void Handle(T myConfiguration); 
} 

public class MyConfiguration : IConfiguration 
{ 
} 

public class MyHandler : IHandler<MyConfiguration> 
{ 
    public void Handle(MyConfiguration myConfiguration) 
    { 
     Console.WriteLine("Handling my stuff..."); 
    } 
} 

答えて

2

これはうまくいかないでしょう。
理由は次のとおりです。
IHandler<IConfiguration>HandleのパラメータとしてIConfigurationを必要とします。あなたの最初の行が有効になる場合
、次のようにコンパイルします:

明らか
MyOtherConfiguration config = new MyOtherConfiguration(); 
IHandler<IConfiguration> test = new MyHandler(); 
test.Handle(config); 

MyHandler.HandleMyConfigurationまたは派生型を望んでいるので、これは、正しくありません。この答えの私の以前のバージョンで説明したようにコントラ分散を使用して

では、次の操作を行うことができます:

IHandler<MyDerivedConfiguration> test = new MyHandler(); 

MyConfigurationに由来するMyDerivedConfigurationで。

+0

それを試しても、それはまだ動作しません。 Tを試してみたところ、割り当ては動作しますが、ハンドラの実装はコンパイルされませんでした。 – MatteS

+0

@マットS:そうです。更新された回答をご覧ください。 –

+0

ありがとう、今は完全になぜこのdoesntの仕事を私に明確に。私は病気が私のデザインを考え直さなければならないと思う。そうでない場合は、リフレクションを使用してハンドラに呼び出すのが適切かもしれません。 – MatteS

関連する問題