【问题标题】:Difficulty getting Unity dependency injection working with WebAPI, and OWIN难以让 Unity 依赖注入与 WebAPI 和 OWIN 一起使用
【发布时间】:2016-08-19 18:14:33
【问题描述】:

当我尝试在我的应用程序上调用控制器 API 端点时,我收到此错误:

   {
  "Message": "An error has occurred.",
  "ExceptionMessage": "An error occurred when trying to create a controller of type 'ProviderController'. Make sure that the controller has a parameterless public constructor.",
  "ExceptionType": "System.InvalidOperationException",
  "StackTrace": "   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n   at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()",
  "InnerException": {
    "Message": "An error has occurred.",
    "ExceptionMessage": "Type 'mynamespace.api.controllers.ProviderController' does not have a default constructor",
    "ExceptionType": "System.ArgumentException",
    "StackTrace": "   at System.Linq.Expressions.Expression.New(Type type)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"
  }
} 

我的配置如下,我使用的是Unity.WebAPI库:

Startup.cs

    public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = GlobalConfiguration.Configuration;
        config.DependencyResolver = new UnityDependencyResolver(UnityConfig.GetConfiguredContainer());
        app.UseWebApi(WebApiConfig.Register());
        app.UseCors(CorsOptions.AllowAll);


        config.EnsureInitialized();

    }

UnityConfig.cs:

public static class UnityConfig
{
    #region Unity Container

    /// <summary>
    /// Load types in Unity Container 
    /// </summary>
    private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
    {
        var container = new UnityContainer();
        RegisterTypes(container);
        return container;
    });

    /// <summary>
    /// Gets the configured Unity container.
    /// </summary>
    public static IUnityContainer GetConfiguredContainer()
    {
        return container.Value;
    }

    #endregion


    /// <summary>
    /// Register the types into Unity Container.
    /// </summary>
    /// <param name="container"></param>
    public static void RegisterTypes(UnityContainer container)
    {
        container.RegisterType<IProviderService, ProviderService();  
    } 
}

ProviderController.cs:

public class ProviderController : ApiController
{
    private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
    private readonly IProviderService providerService;      

    public ProviderController(IProviderService providerService)
    {
        providerService = providerService;
    }

    //Controller API Methods
}

ProviderService.cs:

    public ProviderService()
    {
        this.serviceClient = new ServiceClientAdapter();
    }

我整个上午都在阅读各种线程,但无法弄清楚我哪里出错了。如果我删除 Unity 并直接在控制器中实例化一个新的 ProviderService,一切正常。

【问题讨论】:

    标签: c# asp.net-web-api2 unity-container owin


    【解决方案1】:

    我的问题是一个小小的疏忽。 Startup.cs 中对 UseWebApi 的调用没有将 HttpConfiguration 配置对象作为参数,而是声明它是自己的。这意味着 WebAPI 和 Unity 配置了不同的 HTTPConfiguration 对象,因此 WebAPI 不知道 Unity。

    【讨论】:

    • 我想我可能有类似的问题。我尝试从启动类向 DependencyResolver 注入配置对象,但没有成功!你是怎么解决的?
    • 如果你看我上面的例子,对于 Startup.cs,第一行的 config 对象用于配置 Unity。然后当调用 app.UseWebApi 时,会创建一个新的配置对象并将其传递给它。这就是问题所在,应该传入第一行声明的配置。
    • 谢谢兄弟!它有帮助。
    【解决方案2】:

    答案已经有了!只是为了方便或更短的代码。

    你可以写一个方法

        public static void RegisterComponents()
        {
            var container = new UnityContainer();
    
            // register all your components with the container here
            // it is NOT necessary to register your controllers
    
            container.RegisterType<IProviderService, ProviderService>();
    
            GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
        }
    

    Startup.cs:

        public void Configuration(IAppBuilder app)
        {
            ConfigureOAuth(app);
            HttpConfiguration config = GlobalConfiguration.Configuration;
            app.UseWebApi(config);
        }
    

    然后添加 UnityConfig.RegisterComponents();进入全局文件

    【讨论】:

      猜你喜欢
      • 2016-09-28
      • 1970-01-01
      • 2019-04-13
      • 1970-01-01
      • 2015-05-27
      • 2016-06-25
      • 1970-01-01
      • 2021-02-09
      • 1970-01-01
      相关资源
      最近更新 更多