サーチ…


備考

依存性注入のウィキペディアの定義は:

ソフトウェアエンジニアリングでは、依存関係注入は、依存関係を解決するための制御の逆転を実装するソフトウェア設計パターンです。依存関係は、使用可能なオブジェクト(サービス)です。インジェクションとは、それを使用する依存オブジェクト(クライアント)への依存関係の引き渡しです。

** このサイトには、5歳の子供に依存性注射を説明する方法に関する質問に対する回答が掲載されています。 John Munschによって提供された最も高い評価を得た答えは、(想像上の)5歳の尋問者を対象とした驚くほど正確なアナロジーを提供します:あなたが行って自分自身で冷蔵庫から物事を取り出すと、問題を引き起こす可能性があります。あなたはドアを開いたままにしておくかもしれません、ママかパパがあなたに持ってほしくない何かを得るかもしれません。あなたは私たちが持っていない、あるいは期限切れの何かを探しているかもしれません。あなたがしなければならないことは、「昼食で飲むものが必要です」という必要性を述べることです。そして、座って食べるときに何かがあることを確認します。これはオブジェクト指向のソフトウェア開発の面でこれが何を意味しているのですか?共同授業(5歳児)はインフラストラクチャ(親)に依存して

**このコードはMEFを使用してDLLを動的にロードし、依存関係を解決します。 ILoggerの依存関係は、MEFによって解決され、ユーザークラスに注入されます。ユーザークラスはILoggerの具体的な実装を受け取りません。どのタイプのロガーを使用しているのか分かりません。**

MEFを使用した依存性注入

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

[Export(typeof(ILogger))]
[ExportMetadata("Name", "Console")]  
public class ConsoleLogger:ILogger
{
    public void Log(string message)
    {
        Console.WriteLine(message);
    }
}

[Export(typeof(ILogger))]
[ExportMetadata("Name", "File")]  
public class FileLogger:ILogger
{
    public void Log(string message)
    {
        //Write the message to file
    }
}

public class User
{  
    private readonly ILogger logger;
    public User(ILogger logger)   
    {
        this.logger = logger;
    }
    public void LogUser(string message)
    {
        logger.Log(message)  ;
    }
}

public interface ILoggerMetaData
{
    string Name { get; }
}

internal class Program
{
    private CompositionContainer _container;
    
    [ImportMany]
    private IEnumerable<Lazy<ILogger, ILoggerMetaData>> _loggers;
    
    private static void Main()
    {            
        ComposeLoggers();
        Lazy<ILogger, ILoggerMetaData> loggerNameAndLoggerMapping = _ loggers.First((n) => ((n.Metadata.Name.ToUpper() =="Console"));
        ILogger logger= loggerNameAndLoggerMapping.Value
        var user = new User(logger);
        user.LogUser("user name");
    }
    
    private void ComposeLoggers()
    {
        //An aggregate catalog that combines multiple catalogs
        var catalog = new AggregateCatalog();
        string loggersDllDirectory =Path.Combine(Utilities.GetApplicationDirectory(), "Loggers");
        if (!Directory.Exists(loggersDllDirectory ))
        {
            Directory.CreateDirectory(loggersDllDirectory );
        }
        //Adds all the parts found in the same assembly as the PluginManager class
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
        catalog.Catalogs.Add(new DirectoryCatalog(loggersDllDirectory ));
        
        //Create the CompositionContainer with the parts in the catalog
        _container = new CompositionContainer(catalog);
        
        //Fill the imports of this object
        try
        {
            this._container.ComposeParts(this);
        }
        catch (CompositionException compositionException)
        {
            throw new CompositionException(compositionException.Message);
        }
    } 
}

依存性注入C#とASP.NET with Unity

まず、私たちのコードでdepedency injectionを使うべき理由は?私たちのプログラムでは、他のクラスと他のクラスを分離したいと考えています。たとえば、次のようなコードを持つAnimalControllerクラスがあります。

public class AnimalController()
{
    private SantaAndHisReindeer _SantaAndHisReindeer = new SantaAndHisReindeer();

    public AnimalController(){
            Console.WriteLine("");
    }
}

このコードを見ると、すべてが問題ないと思っていますが、AnimalControllerはオブジェクト_SantaAndHisReindeerに依存しています。自動的に私のコントローラはテストに悪く、私のコードの再利用性は非常に難しいでしょう。

私たちがDepedency Injectionを使用し、 ここでインターフェイスを取るべき理由についての非常に良い説明。

UnityがDIを処理するようにしたい場合、これを達成する道は非常に簡単です:) NuGet(パッケージマネージャ)を使うと、コードへの統一性を簡単にインポートできます。

Visual Studio Tools - > NuGet Package Manager - >ソリューションパッケージの管理 - >検索入力の統一 - >プロジェクトの選択 - >インストールをクリック

今すぐ素敵なコメントを持つ2つのファイルが作成されます。

App-Dataフォルダ内のUnityConfig.csとUnityMvcActivator.cs

UnityConfig - RegisterTypesメソッドでは、コンストラクタに注入される型を見ることができます。

namespace Vegan.WebUi.App_Start
{

public class UnityConfig
{
    #region Unity Container
    private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
    {
        var container = new UnityContainer();
        RegisterTypes(container);
        return container;
    });

    /// <summary>
    /// Gets the configured Unity container.
    /// </summary>
    public static IUnityContainer GetConfiguredContainer()
    {
        return container.Value;
    }
    #endregion

    /// <summary>Registers the type mappings with the Unity container.</summary>
    /// <param name="container">The unity container to configure.</param>
    /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
    /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
    public static void RegisterTypes(IUnityContainer container)
    {
        // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
        // container.LoadConfiguration();

        // TODO: Register your types here
        // container.RegisterType<IProductRepository, ProductRepository>();

        container.RegisterType<ISanta, SantaAndHisReindeer>();
        
     }
 }
}

UnityMvcActivator - >また、このクラスがUnityをASP.NET MVCと統合すると言う素敵なコメントがあります

using System.Linq;
using System.Web.Mvc;
using Microsoft.Practices.Unity.Mvc;

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(Vegan.WebUi.App_Start.UnityWebActivator), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(Vegan.WebUi.App_Start.UnityWebActivator), "Shutdown")]
    
namespace Vegan.WebUi.App_Start
{
/// <summary>Provides the bootstrapping for integrating Unity with ASP.NET MVC.</summary>
public static class UnityWebActivator
{
    /// <summary>Integrates Unity when the application starts.</summary>
    public static void Start() 
    {
        var container = UnityConfig.GetConfiguredContainer();

        FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
        FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));

        // TODO: Uncomment if you want to use PerRequestLifetimeManager
        // Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
    }

    /// <summary>Disposes the Unity container when the application is shut down.</summary>
    public static void Shutdown()
    {
        var container = UnityConfig.GetConfiguredContainer();
        container.Dispose();
    }
}
}

今度は、コントローラをクラスSantAndHisReindeerから切り離すことができます:)

 public class AnimalController()
    {
        private readonly SantaAndHisReindeer _SantaAndHisReindeer;

        public AnimalController(SantaAndHisReindeer SantaAndHisReindeer){

                _SantAndHisReindeer = SantaAndHisReindeer;
        }
    }

アプリケーションを実行する前に最後に行うべきことが1つあります。

Global.asax.csでは、UnityWebActivator.Start()という新しい行を追加する必要があります。これは、Unityを設定し、タイプを登録します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Vegan.WebUi.App_Start;

namespace Vegan.WebUi
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            UnityWebActivator.Start();
        }
    }
}


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow