拡張可能なアプリケーションをサポートするために、ASP.NET MVC 4 で MEF 2 を使用しようとしています。この質問には実際には 2 つの部分があります (問題ないことを願っています)。
Microsoft.Composition と MVC コンテナー コード ( MEF/MVC デモ ソース) を使用してICoreService
、、、、およびの DI として Ninject を置き換えるにはどうすればよいでしょうか?ICoreRepository
IUnitOfWork
IDbContext
Ninject と MVC コンテナーの両方を同時に使用することはできないようです (多くの人が「当たり前」と言っていると思います) ので、可能であれば MEF を使用したいと考えています。[Export]
Web プロジェクトに加えて 2 つのアセンブリにまたがって、Ninject を削除し、関連する実装のそれぞれに属性を設定しようとしましSave()
たが、エラーなしで持続できませんでした。私はそれをシングルトンの問題と解釈しましたが、それを整理する方法を理解できませんでした(含む[Shared]
)。実行時に複数のアセンブリを動的にロードするにはどうすればよいですか? 特定の DLL をロード
するために使用する方法は理解していますが、アプリケーションを適切に拡張可能にするためには、Microsoft.Composition パッケージ (CompositionContainer.AddAssemblies()
おもう?);IPluggable
独自の UI、サービス、およびリポジトリ レイヤーを含み、コア サービス/リポジトリにも結び付けられるすべての (または何でも) アセンブリをロードできるようにします。
EDIT 1
もう少し読むと、実際にはシングルトンの問題である最初の問題が解決されました。CoreDbContext にアタッチ[Shared(Boundaries.HttpRequest)]
すると、永続性の問題が解決されました。単純に試してみると[Shared]
、「シングルトン化」がアプリケーション レベル (クロス リクエスト) に拡張され、編集されたオブジェクトが既に EF キャッシュにあるという例外がスローされました。
EDIT 2
以下の Nick Blumhardt の回答から「肉」をロードする反復アセンブリを使用して、Global.asax.cs コードを更新しました。彼のコードの標準の MEF 2 コンテナーは、おそらく MEF 2(?) MVC コンテナーを使用しているため、私のコードでは機能しませんでした。概要: 以下にリストされているコードは、希望どおりに機能するようになりました。
CoreDbContext.cs (Data.csproj)
[Export(typeof(IDbContext))]
[Shared(Boundaries.HttpRequest)]
public class CoreDbContext : IDbContext { ... }
CoreRepository.cs (Data.csproj)
[Export(typeof(IUnitOfWork))]
[Export(typeof(ICoreRepository))]
public class CoreRepository : ICoreRepository, IUnitOfWork
{
[ImportingConstructor]
public CoreRepository(IInsightDbContext context)
{
_context = context;
}
...
}
CoreService.cs (Services.csproj)
[Export(typeof(ICoreService))]
public class CoreService : ICoreService
{
[ImportingConstructor]
public CoreService(ICoreRepository repository, IUnitOfWork unitOfWork)
{
_repository = repository;
_unitOfWork = unitOfWork;
}
...
}
UserController.cs (Web.csproj)
public class UsersController : Controller
{
[ImportingConstructor]
public UsersController(ICoreService service)
{
_service = service;
}
...
}
Global.asax.cs (Web.csproj)
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
CompositionProvider.AddAssemblies(
typeof(ICoreRepository).Assembly,
typeof(ICoreService).Assembly,
);
// EDIT 2 --
// updated code to answer my 2nd question based on Nick Blumhardt's answer
foreach (var file in System.IO.Directory.GetFiles(Server.MapPath("Plugins"), "*.dll"))
{
try
{
var name = System.Reflection.AssemblyName.GetAssemblyName(file);
var assembly = System.Reflection.Assembly.Load(name);
CompositionProvider.AddAssembly(assembly);
}
catch
{
// You'll need to craft exception handling to
// your specific scenario.
}
}
}
}