我试图使用Unity根据这篇文章注入依赖项:
http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
以下是我在global.asax中的内容
void ConfigureApi(HttpConfiguration config)
{
var unity = new UnityContainer();
unity.RegisterType<CustomerController>();
unity.RegisterType<TPS.Data.Can.IUnitOfWork, TPS.Data.Can.EFRepository.UnitOfWork>(new HierarchicalLifetimeManager());
config.DependencyResolver = new IoCContainer(unity);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ConfigureApi(GlobalConfiguration.Configuration);
}
这是我的API控制器:
public class CustomerController : ApiController
{
private TPS.Data.Can.IRepository<tblCustomer> _repo;
private TPS.Data.Can.IUnitOfWork _uow;
public CustomerController() { }
public CustomerController(TPS.Data.Can.IUnitOfWork uow) {
_uow = uow;
_repo = uow.CustomerRepository;
}
// GET api/customer/5
public IEnumerable<Customer> Get()
{
string identity = HttpContext.Current.User.Identity.Name;
//REFACTOR THIS
if (String.IsNullOrWhiteSpace(identity))
identity = "chardie";
var customers = from c in _repo.Get()
where c.SalesRep == identity
select new Customer
{
IDCUST = null,
CustCode = c.CustCode,
CustName = c.CustName
};
return customers.ToList();
}
当我第一次开始调试我的应用程序时,这是有效的。如果我在参数化构造函数中设置断点,那么当我第一次点击Web API时会遇到断点。当我在浏览器中点击刷新时,构造函数 not 被调用,依赖项不会被注入,而Get()操作会抛出异常,因为预期的存储库为null。
有人能告诉我为什么在第一次请求后没有调用我的构造函数吗?
谢谢!
克里斯
修改
FWIW,我完全从Web API控制器中删除了无参数构造函数,在我的第二个请求中,我得到了异常:
Type 'TPS.Website.Api.CustomerController' does not have a default constructor
所以看来我在第一个请求上注入了repo依赖项,但之后Web API控制器的每个实例化都是通过无参数构造函数完成的。
答案 0 :(得分:0)
您没有为控制器指定生命周期。 MSDN states
如果未指定生命周期的值,则实例将具有 默认的容器控制生命周期。它将返回一个引用 在每次调用Resolve时对原始对象。
如果IUnitOfWork
依赖是暂时的,那么控制器也应该是瞬态的。所以试试
unity.RegisterType<CustomerController>(new TransientLifetimeManager());
这可能无法解决整个问题,但它听起来像是其中的一部分。你当然不应该需要无参数构造函数。
答案 1 :(得分:0)
我有这个,因为我使用它返回我的解析器为我的依赖范围,然后将容器放在dispose中。因此,在第一次请求后,容器被处理掉了。
答案 2 :(得分:0)
看起来是因为你没有为Unity容器使用单例模式。
拥有私有静态变量而不是var container = new UnityContainer();
internal static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => new UnityContainer());
然后使用.Value属性在代码中访问。