我正在使用 Mvc3 和Unity.Mvc3来构建一个可测试和解耦的站点,但我显然做错了什么。
在我的Application_Start()
我注册了一个依赖:
// container is a property of the MvcApplication
// and the HierarchicalLifetimeManager should make sure that the registrations
// only last for this request (or should it?)
_container.Register<Interface, Class>(new HierarchicalLifetimeManager())
然后在Session_Start()
我尝试解决我的依赖关系以将一些数据保存到会话中:
var obj = _container.Resolve<Interface>();
此时我得到一个异常说Unity无法解析接口,但我以为我为那个接口注册了一个类???
我很茫然,找到解决方案越来越难。
编辑:
这是我的整个代码,省略了一些不必要的部分:
public class MvcApplication : System.Web.HttpApplication
{
// as EDIT 2 says, this is wrong...
//private IUnityContainer _container = new UnityContainer();
protected void Application_Start()
{
// mvc stuff, routes, areas and whatnot
// create container here and it works, almost
var container = new UnityContainer();
// register dependencies
string connectionString = "String from config";
container.RegisterInstance<DbContext>(new CustomContext(connectionString), new HierarchicalLifetimeManager())
.RegisterType<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager())
.RegisterType(typeof(IRepository<>), typeof(Repository<>), new HierarchicalLifetimeManager());
// register controller resolver
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
// if i try to resolve repos here, it works and they all have the same context
// just like the unit of work
}
protected void Session_Start()
{
// here the container complains that it can't resolve the interface
// wrong
//var userRepo = _container.Resolve<IRepository<User>>();
// right, but still failes, because it is resolving DbContext
// instead of using the CustomContext instance
var userRepo = DependencyResolver.Current.GetService<IRepository<User>>();
// save some user data to session
}
}
public class SampleController : Controller {
// here the container tries to resolve the System.Data.Entity.DbContext
// instead of just giving the repo that instance that I registered
public SampleController(IRepository<Entity> repo) {
}
}
我显然在这个工作单元,依赖注入的东西上失败了,最糟糕的是我不知道为什么......所以在我开始拔牙之前请帮忙。
编辑2:
部分在那里。如果我按上述方式创建容器,它会在Session_Start()
. 如果我在 中创建它Application_Start()
作为局部变量,并使用DependencyResolver
,它可以工作。怎么打,为什么打我?
但它仍在尝试解决DbContext
而不是CustomContext
实例。
解决方案:
好的,这是交易:
问题1)访问容器Session_Start()
:
如 EDIT 2 中所述,使用本地容器变量可以解决该问题,并通过DependencyResolver
作品访问容器。
问题2)解析注册的数据库上下文实例:
事实证明,注册实例不起作用。但这确实:
container.RegisterType<DbContext, CustomContext>(null, new HierarchicalLifetimeManager(), new InjectionConstructor(connectionString))
但我并不真正感到满意,因为我仍然不明白为什么会这样。看来我很长一段时间都需要读一本书什么的。
提前谢谢了。