6

私はそのコンストラクタでIMyDependencyをとるサービスを持っています。 IMyDependency、MyDependency、およびサービスはすべて同じアセンブリ内に存在します。 MyDependencyには、パラメータのない単一のパブリックコンストラクタがあります。funqのservicestack - 慣習による自動配線

驚いたことに、これは動作しませんでした:

container.RegisterAutoWired<IMyDependency>(); 

それは "System.NullReferenceException" をスローします。

私はこれを行う場合、それは動作します:

container.RegisterAutoWiredAs<MyDependency, IMyDependency>(); 

をしかし、その後、ので、この行います

container.RegisterAs<MyDependency, IMyDependency>(); 

だから、違いは何ですか? 「自動配線」が具体的な実装を見つけることができず、依存関係を必要とするサービスを解決できるかどうかに違いがない場合、自動配線とは何ですか?

Funqは慣例により具体的な実装を見つけることができると思われますか?もしそうなら、同じ命名ではないなら、その慣例は何ですか?

ありがとうございました。

答えて

4

このような簡単なクエリの場合は、ソースに接続するだけです(例:ここRegisterAutoWiredのソースコードは次のとおりです。

public IRegistration<T> RegisterAutoWired<T>() 
{ 
    var serviceFactory = GenerateAutoWireFn<T>(); 
    return this.Register(serviceFactory); 
} 

それは、具体的な実装オーバーオート有線工場を生成します。インタフェースには実装がありません。具体的なクラスである必要があります。

そしてRegisterAsのソースコード:

public IRegistration<TAs> RegisterAs<T, TAs>() where T : TAs 
{ 
    return this.RegisterAutoWiredAs<T, TAs>(); 
} 

あなたの代わりにRegisterAutoWiredAsを使用することができるだけ短く別名です。

+0

だから私はこれを正しく理解していれば、私がやるべきこと: container.RegisterAutoWired (); しかし、これを実行すると、実行時に依存関係のあるサービスを呼び出すと、「IMyDependency型の依存関係を解決できませんでした」というメッセージが表示されます。コンテナが登録された具体的な型に対応するインタフェースを見つけることができないように見えるので、私はこのメソッドの目的についてはまだ不明です。 –

+3

'MyDependency>を登録すれば、' MyDependency'プロパティをすべて注入するよりも簡単に登録できます。 IMyDependencyプロパティを挿入する場合は、RegisterAs を呼び出す必要があります。 – mythz

+1

私のプロジェクトでは、約200クラスの習慣をMyClass:IMyClassと似ています。だから私は新しいクラスを実装するたびにこれに応じて、または削除することができますか?ユニティ、ウィンザー、StructureMapは慣習によりオートワイヤーを持っています。 – nerijus

8

「アセンブリを検索し、慣例に基づいてServiceStack IOCでクラスを自動的に登録するソリューションを実装するにはどうすればよいですか?

  1. があなたの注入可能なクラスが実装するインタフェースを作成します。

    もしそうなら、私はあなたのためのソリューションを持っているかもしれません。

  2. 注入可能なクラスでそのインターフェースを実装してください。
  3. ブートストラップコードでは、リフレクションを使用してアセンブリを検索し、注入可能なインターフェイスを実装するすべてのクラスのリストを取得します。
  4. リフレクションを使用して、慣習に基づいてクラス名とインターフェイスを取得します。
  5. ServiceStack IOCメソッドRegisterAutoWiredTypeを呼び出し、クラスとインターフェイスを渡して登録します。たとえば、

私たちの命名規則は、クラス名IClassNameの場合:

private static void RegisterCustomTypes(Container container) 
{ 
    //Get the Assembly Where the injectable classes are located. 
    var assembly = Assembly.GetAssembly(typeof(IInjectable)); 

    //Get the injectable classes 
    var types =assembly.GetTypes() 
    .Where(m => m.IsClass && m.GetInterface("IInjectable") != null); 

    //loop through the injectable classes 
    foreach (var theType in types) 
    { 
    //set up the naming convention 
    var className = theType.Name; 
    var interfaceName = string.Concat("I", className); 
    //create the interface based on the naming convention 
    var theInterface = theType.GetInterface(interfaceName); 
    //register the type with the convention 
    container.RegisterAutoWiredType(theType, theInterface); 
    } 
} 

public interface IInjectable 
{ 

} 

//This class can be injected 
public interface ITestManager : IInjectable 
{ 
    void Execute(int id); 
} 

public class TestManager : ITestManager 
{ 
    public void Execute(int id) 
    { 
     throw new System.NotImplementedException(); 
    } 
} 
+0

私の元の投稿以来、私はFuncが組み込み検索を組み込んでいないことを理解しました。ここで示唆したように独自のリフレクションを実装している場合、Ninjectなどの別のソリューションでは、Funcを使用する際にパフォーマンス(パフォーマンスなど)が残っていると思いますか? –

+0

わかりません。多分神話はそれについていくつかの指針を持っていますか? –

+1

@Saber、DIはウェブアプリケーションの起動時に一度だけ実行されます。パフォーマンスの差は無視できます。ウィンザーやニンジェ...など、彼らはすべて良いです。私がFunqを他の人よりも使う理由は、SSに付属しているので、SSパッケージから分離した別のIoCを維持するのが面倒です。 – Tom

関連する問題