4

システム依存の EFcontexts とサービスを実装するプラグイン アセンブリを含む asp.net mvc 3 Web アプリケーションがあります。

たとえば、一般的に次のようなアセンブリがあります。

System1Controller : IController // from System.Web.Mvc

ISystem1Service {
    IList<System1Type> GetOperation(string something);
}

System1Service : ISystem1Service 
{
    private ISystem1Entities context;
    public System1Service(ISystem1Entities context)
    {
        this.context = context;
    }
}

ISystem1Entities
{
    IDbSet<System1Type> Operations { get; set; }
}

System1Entities : DbContext, ISystem1Entities

Unity Bootstrapper を使用して Bootstrapper.Initialize() を呼び出すと、次の BuildUnityContainer() 実装で動作します

private static IUnityContainer BuildUnityContainer()
{
    var theContainer = new UnityContainer();
    var connectionString = ConfigurationManager.ConnectionStrings["WebAppConnectionString"];
    if (connectionString == null)
    {
        throw new ApplicationException("The ConnectionString is not defined.");
    }

    // register all your components with the container here
    // it is NOT necessary to register your controllers
    theContainer.RegisterType<ISystem1Entities, System1Entities>(
        new HierarchicalLifetimeManager(), 
        new InjectionConstructor(connectionString.ConnectionString));

    theContainer.RegisterType<ISystem1Service, System1Service>();

    var factory = new UnityControllerFactory(theContainer);
    ControllerBuilder.Current.SetControllerFactory(factory);

    return theContainer;
}

コンパイル時に「不明な」アセンブリをロードし、それらに含まれる型を登録し、Web アプリケーションが必要に応じてコントローラー、サービス、コンテキストを参照できるように、ブートストラップをリファクタリングしたいと考えています。

Unity AutoRegistraionプロジェクトを見てきましたが、私が望む実装の近くにいるように見えますが、次のアイデアを実装する方法がわかりません:

BootStrapper.BuildUnityConfiguration
    Initialize Container
    RegisterMyAssemblies()

「RegisterMyAssemblies」プロセスでアセンブリのワイルドカード リストを登録してから、個々のアセンブリ内の型の登録に進みます。助言がありますか?

4

2 に答える 2

5

アプリケーションのメイン ブートストラップ (コンポジション ルート) を使用してこれらのプラグイン アセンブリを構成しようとしないでください。メインプログラムはどのタイプを登録するか、またそれらのタイプをどのくらいの期間までに登録する必要があるかを認識していないため、正しく理解するのは困難です。

代わりに、各プラグイン アセンブリに独自のブートストラップ メソッドを持たせ、アプリケーションのコンテナー インスタンスをこのプラグイン ブートストラップに渡します。

たとえば、IBootstrapperコア アセンブリでインターフェイスを定義し、各プラグイン アセンブリにこのインターフェイスを実装させることができます。例えば:

public class System1Bootstrapper : IBootstrapper
{
    void IBootstrapper.Bootstrap(IUnityContainer container)
    {
        var conString = ConfigurationManager
            .ConnectionStrings["WebAppConnectionString"];

        if (conString == null)
        {
            throw new ApplicationException(
                    "The ConnectionString is not defined.");
        }

        // register all your components with the container here
        // it is NOT necessary to register your controllers
        container.RegisterType<ISystem1Entities, System1Entities>(
            new HierarchicalLifetimeManager(), 
            new InjectionConstructor(conString.ConnectionString));

        container.RegisterType<ISystem1Service, System1Service>();
    }
}

アプリケーションの構成ルートで、次のコードを追加するだけで、すべてのプラグイン タイプを登録できるようになりました。

var pluginBootstrappers =
    from Assembly assembly in BuildManager.GetReferencedAssemblies()
    from type in assembly.GetExportedTypes()
    where typeof(IBootstrapper).IsAssignableFrom(type)
    select (IBootstrapper)Activator.CreateInstance(type);

pluginBootstrappers.ToList().ForEach(b => b.Bootstrap(container));
于 2012-10-08T14:56:06.137 に答える
0

これは確かにプラグですが、NuGet の Unity Automapper を見てください。まさにこの種のことを行うことができます-型またはアセンブリ名のコレクションを提供するだけです。インターフェイスに基づいて依存関係を自動的に結び付けます-具体的なマッピング。また、内部型で動作するため、インターフェイスを公開し、それらのインターフェイスのプロバイダーを内部にすることで、「適切な」DIP を実行できます。

于 2012-10-09T09:53:20.437 に答える