Unity IoC解析通用服务和通用存储库

时间:2012-06-14 10:49:33

标签: c# entity-framework dependency-injection unity-container repository-pattern

使用ASP.NET MVC和Entity Framework时,尝试实现通用存储库和通用服务,并使Unity Ioc解决所有问题:

我试图让Unity Ioc使用参数注入向控制器注入一个通用服务,但是类型解析失败了这个错误消息:

  

尝试获取类型实例时发生激活错误   ISupplierService当前的构建操作(构建密钥Build   密钥[MyApp.Services.Implementation.SupplierService,null])失败:   尝试获取类型实例时发生激活错误   IGenericRepository 1, key \"\" Resolution of the dependency failed: The current type, MyApp.Repository.Interfaces.IGenericRepository 1 [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);

1 个答案:

答案 0 :(得分:3)

使用UnityAutoRegistration进行实验,而最新版本仍然“新鲜”,我对此并不满意。 TecX project on codeplex包含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);

应注册所有接口/服务和接口/存储库对。该公约将SupplierService注册为ISupplierService等的实施。 使用两个开放泛型类型(RegisterTypeIGenericRepositoy<>)对GenericRepository的附加调用将您的通用存储库接口映射到通用存储库类。 Unity会自动为您关闭类型定义(即IGenericRepository<Supplier>将映射到GenericRepository<Supplier>)。