Web API控制器参数化构造函数仅在后续请求中调用一次,无参数构造函数

时间:2013-03-19 13:54:39

标签: asp.net asp.net-mvc asp.net-web-api

我试图使用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控制器的每个实例化都是通过无参数构造函数完成的。

3 个答案:

答案 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属性在代码中访问。