使用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);
答案 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
等的实施。
使用两个开放泛型类型(RegisterType
和IGenericRepositoy<>
)对GenericRepository
的附加调用将您的通用存储库接口映射到通用存储库类。 Unity会自动为您关闭类型定义(即IGenericRepository<Supplier>
将映射到GenericRepository<Supplier>
)。