6

コンストラクターで IMyDependency を取るサービスがあります。IMyDependency、MyDependency、およびサービスはすべて、同じアセンブリ内にあります。MyDependency には、単一のパブリックなパラメーターなしのコンストラクターがあります。

驚いたことに、これはうまくいきませんでした:

container.RegisterAutoWired<IMyDependency>();

「System.NullReferenceException」をスローします。

これを行うと機能します:

container.RegisterAutoWiredAs<MyDependency, IMyDependency>();

しかし、次のようになります。

container.RegisterAs<MyDependency, IMyDependency>();

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

Funq は慣習によって具体的な実装を見つけることができるはずですか? もしそうなら、同名ではないにしても、その慣習は何ですか?

ありがとう。

4

2 に答える 2

8

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

もしそうなら、私はあなたのための解決策を持っているかもしれません:

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

たとえば、命名規則が ClassName 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();
    }
}
于 2013-10-15T13:52:24.413 に答える
5

このような単純なクエリの場合は、ソースに連絡するのが最善です。たとえば、RegisterAutoWiredのソース コードは次のとおりです。

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

Concrete 実装上で自動配線されたファクトリを生成します。インターフェイスには実装がありません。具体的なクラスである必要があります。

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

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

これは、RegisterAutoWiredAs の代わりに使用できる短いエイリアスです。

于 2013-04-26T01:03:38.550 に答える