1

私は依存性注入の初心者です。インターフェイスインジェクションを使用して依存性注入を実装する方法を理解しましたが、依存性注入は3つの方法で実装できるか、それ以上の方法で実装できることがわかっています。

  1. インターフェイスインジェクション:このサービスは、消費者が実装する必要のあるインターフェイスを提供します。インターフェイスは、実行時に特定の動作を公開します。
  2. セッターインジェクション:依存オブジェクトは、依存関係をインジェクトするための「セッター」メソッドを公開します。
  3. コンストラクターの注入:依存性はクラスコンストラクターを介して注入されます

そのため、SetterインジェクションまたはUnityを使用したコンストラクターインジェクションのいずれかを使用して依存性注入を実装する方法を理解するのに役立つサンプルコードをいくつか探しています。依存性注入を実装するさまざまな方法のための小さな小さなコードの助けをいただければ幸いです。

私は団結を使ったインターフェースインジェクションしか知りません。これが、Unityを使用したインターフェイスインジェクションを使用して正常に機能する私のコードです。

public interface ILogger
{
     void Write(string message);
}

We have define three classes as follows.

public class FileLogger : ILogger
{
     public void Write(string message)
     {
          //Do somthing
     }
}

public class SQLLogger : ILogger
{
     public void Write(string message)
     {
          //Do somthing
     }
}

public class WindowsEventLogger : ILogger
{
     public void Write(string message)
     {
          //Do somthing
     }
}

これらのクラスを登録し、構成ファイル(つまり、app.config)のインターフェースにマップする必要があります。

<configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <alias type="UnityTest.ILogger, UnityTest" alias="ILogger" />
    <namespace name="UnityTest"/>

    <container>
      <register mapTo="UnityTest.FileLogger, UnityTest" name="MyFileLogger" type="ILogger"/>
      <register mapTo="UnityTest.SQLLogger, UnityTest" name="MySQLLogger" type="ILogger"/>
      <register mapTo="UnityTest.WindowsEventLogger, UnityTest" name="MyWindowsEventLogger" type="ILogger"/>
    </container>
</unity>

注:名前属性は、レジスタタグで重要です。

最後に、このマップをコードに使用する必要があります。ですから、特定の国にとってどちらが好ましいかを知る必要があります。

次のように、ディクショナリオブジェクトを使用してこのマッピングを維持できます。

IDictionary<string, string> loggers = new Dictionary<string, string>();
loggers.Add("USA", "MyFileLogger");
loggers.Add("GBR", "MySQLLogger");
loggers.Add("IN", "MyWindowsEventLogger");

データベース、xml、または別のソースからデータを取り込むことができます。次に、Writeメソッドを呼び出します。

IUnityContainer container = new UnityContainer();
container.LoadConfiguration();

ILogger logger = container.Resolve<ILogger>(loggers[objUser.countryCode]);
logger.Write("Hello World");

新しい質問

ユニティを使用した建設注入のサンプルコードを見つけましたが、それでも1つはっきりしていません。これがコードです。

public class CustomerService
{
  public CustomerService(LoggingService myServiceInstance)
  { 
    // work with the dependent instance
    myServiceInstance.WriteToLog("SomeValue");
  }
} 

IUnityContainer uContainer = new UnityContainer();
CustomerService myInstance = uContainer.Resolve<CustomerService>();

私たちが書くときuContainer.Resolve<CustomerService>();、LoggingServiceクラスのインスタンスを送信していません。CustomerServiceコンストラクターには。のインスタンスが必要なため、クラスのインスタンスを作成する方法を説明しますLoggingService

この領域は明確ではありません。それがどのように機能するかを私に説明してください。

もう1つの質問は[Dependency]属性です。それは何をするのか、そしてメソッドをいつ属性で装飾する必要があるのか[Dependency]​​です。

4

2 に答える 2

1

コードをベースに。

ILoggerに依存するクラスがあり、ILoggerのデフォルト登録(名前のない登録)がある場合

IUnityContainer container = new UnityContainer();

//fixed
//by default RegisterType will create new instance of the type every time 
//the container resolves the dependancy 
container.RegisterType<ILogger,SomeLoggerImplementation>();
container.RegisterType<Foo>();
container.RegisterType<Bar>();

//will create a new instance of SomeLoggerImplementation using a default ctor, pass it to the constructor of Foo and return the instance of Foo
//if SomeLoggerImplementation has some other dependancies they can be registered in the container too! 
var foo = container.Resolve<Foo>();

//will create a new instance of SomeLoggerImplementation using a default ctor, create a new instance of Bar, 
//Set the value of the Property Logger (but not the Logger2), and return the instance of Bar
var bar = container.Resolve<Bar>();

//Constructor injection
public class Foo
{
    private ILogger _logger;
    public Foo(ILogger logger)
    {
        //if Foo is resolved from the container , the value for the logger parameter will be provided from the container
        _logger = logger;
    }
}


//property injection
public class Bar
{
    //If Bar is resolvced from the container the value for the Logger property will also  be provided from the container
    [Dependency]
    public ILogger Logger { get; set; }

    //this will not be injected
    public ILogger Logger2 { get; set; }

    public Bar()
    {
    }
}
于 2013-01-21T13:24:28.093 に答える
0

まず、解決するクラスを1に登録します(この場合、テストクラスを1に登録します)。Testunityを使用してクラスのインスタンスを解決しようとすると、それも解決されILoggerます。msdnからインジェクション属性を参照できます

セッターインジェクション;

public class Test : ITest
{
    [Dependency("MyFileLogger")]
    public ILogger Logger
    {
       get { return iLogger; }
       set { iLogger = value; }
    }
}

コンストラクターインジェクション;

public class Test : ITest
{
    public Test([Dependency("MyFileLogger")] ILogger logger)
    {
         //// you will have an instance of MyFileLogger
    }
}

質問の2番目の部分では、UnityにLoggingServiceも登録されているため、CustomerServiceが解決されようとすると、コンストラクターインジェクションを使用してLoggingServiceパラメーターが解決されます。つまり、コンテナが解決しようとしたときCustomerServiceLoggingServiceそれを解決するためにそれが必要であることを理解しています。次に、最初にLoggingServiceパラメータを解決してから、解決を試みますCustomerService

于 2013-01-21T13:24:38.993 に答える