1

ASP.NET MVC と Entity Framework を使用し、汎用リポジトリと汎用サービスを実装しようとして、Unity Ioc によってすべてが解決される場合:

パラメーター インジェクションを使用して、Unity Ioc で汎用サービスをコントローラーにインジェクトしようとしていますが、型の解決に失敗して次のエラー メッセージが表示されます。

タイプ ISupplierService のインスタンスを取得しようとしているときにアクティベーション エラーが発生しました現在のビルド操作 (ビルド キー Build Key[MyApp.Services.Implementation.SupplierService, null]) が失敗しました: タイプ IGenericRepository 1, key \"\" Resolution of the dependency failed: The current type, MyApp.Repository.Interfaces.IGenericRepository1 [Entities.Supplierのインスタンスを取得しようとしているときにアクティベーション エラーが発生しました] はインターフェイスであり、構築できません。タイプマッピングがありませんか? (戦略タイプ BuildPlanStrategy、インデックス 3)

エラーメッセージは、IGenericRepository のインスタンスを作成しようとしているのに、実際に SupplierService のインスタンスを作成しようとしていることを意味していることは理解できますが、なぜこのように解決されるのかわかりません。最初の回答によると、タイプが登録されていないことが原因である可能性があります

コントローラーのサービス注入は次のとおりです。

public class SupplierController : Controller
{
    private readonly ISupplierService _service;
    public SupplierController() : this (null) { }
    public SupplierController(ISupplierService service) 
    {
        _service = service; 
    }
    // .. injection fails, service is NULL
}

サプライヤー サービスは、空のインターフェイスと空のクラスです (必要に応じてカスタム メソッドを後で追加できます)。

public partial interface ISupplierService : IGenericService<Supplier> {}  

IGenericService は、単に IGenericRepository のメソッドを再表示します。

public interface IGenericService<T> : IDisposable where T : BaseEntity {}

Global.asax.cs では、IoC コンテナーが作成されます。

var container = new UnityContainer();
var uri = new Uri(Assembly.GetExecutingAssembly().CodeBase);
string path = System.IO.Path.GetDirectoryName(uri.AbsolutePath);
var assemblyPaths = new List<string> 
{
    Path.Combine(path, "MyApp.Repository.Interfaces.dll"),
    Path.Combine(path, "MyApp.Repository.Implementation.dll"),
    Path.Combine(path, "MyApp.Services.Interfaces.dll"),
    Path.Combine(path, "MyApp.Services.Implementation.dll")
};

container
    .ConfigureAutoRegistration()
    .LoadAssembliesFrom(assemblyPaths)
    .ExcludeSystemAssemblies()
    .Include(If.Any, Then.Register())
    .ApplyAutoRegistration();

var serviceLocator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => serviceLocator);
4

1 に答える 1

3

最新のリリースがまだ「新鮮」である間に UnityAutoRegistration を試してみましたが、私はそれに満足していませんでした。codeplexのTecX プロジェクトには、StructureMap 構成エンジンのポートが含まれています。これにより、作業が大幅に楽になる規則がサポートされます。

何かのようなもの

ConfigurationBuilder builder = new ConfigurationBuilder();
builder.Scan(s =>
{
  s.AssembliesFromApplicationBaseDirectory();
  s.With(new ImplementsIInterfaceNameConvention());
}
var container = new UnityContainer();
container.AddExtension(builder);
container.RegisterType(typeof(IGenericRepository<>), typeof(GenericRepository<>));
var serviceLocator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => serviceLocator);

Interface/Service と Interface/Repository のペアをすべて登録する必要があります。規則は etc のSupplierService実装として登録されます。2 つのオープン ジェネリック型 (および) を使用したISupplierServiceへの追加の呼び出しは、ジェネリック リポジトリ インターフェイスをジェネリック リポジトリ クラスにマップします。Unity はタイプ定義を自動的に閉じます (つまり、 にマップされます)。RegisterTypeIGenericRepositoy<>GenericRepositoryIGenericRepository<Supplier>GenericRepository<Supplier>

于 2012-06-14T11:38:16.233 に答える