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

本文关键字:存储 服务 IoC Unity | 更新日期: 2023-09-27 18:37:14

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

我正在尝试让 Unity Ioc 使用参数注入将通用服务注入控制器,但类型解析失败,并显示以下错误消息:

尝试获取类型的实例时发生激活错误 ISupplierService 当前生成操作(生成密钥 生成 Key[MyApp.Services.Implementation.SupplierService, null]) 失败: 尝试获取类型的实例时发生激活错误 IGenericRepository 1, key '"'" Resolution of the dependency failed: The current type, MyApp.Repository.Interfaces.IGenericRepository 1[Entities.Supplier], 是一个接口,无法构造。您是否缺少类型 映射? (策略类型构建计划策略,索引 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);

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

在最新版本仍然"新鲜"时尝试了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);

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