简体   繁体   English

添加Owin后,依赖注入中断,没有为此对象定义的无参数构造函数

[英]Dependency Injection broken after adding Owin, no parameterless constructor defined for this object

I have a problem regarding dependency injection in my project, it was working fine before implementing Owin. 我在项目中有关于依赖注入的问题,它在实现Owin之前工作正常。 After I added Owin and made a startup class Issues started to appear. 在我添加了Owin并创建了一个启动类后,问题开始出现。 There is quite some documentation on the issue already. 关于这个问题已有相当多的文件。 But I can't seem to resolve it using any of the other posts about this matter. 但我似乎无法使用任何关于此事的其他帖子来解决它。

The services involved indeed do have a parameterless constructor, the controller has one too, the service stays empty. 所涉及的服务确实有一个无参数构造函数,控制器也有一个,服务保持为空。

I am using the following packages: 我使用以下包:

  • Unity (v3.5.1404) 团结(v3.5.1404)
  • Unity.WebApi.5.1 (v5.2.0) Unity.WebApi.5.1(v5.2.0)
  • Microsoft.AspNet.SignalR.Owin (v1.2.2) Microsoft.AspNet.SignalR.Owin(v1.2.2)
  • Microsoft.AspNet.WebApi.Owin (v5.2.3) Microsoft.AspNet.WebApi.Owin(v5.2.3)
  • Microsoft.AspNet.WebApi.OwinSelfHost (v5.2.3) Microsoft.AspNet.WebApi.OwinSelfHost(v5.2.3)
  • Microsoft.Owin (v3.0.1) Microsoft.Owin(v3.0.1)
  • Microsoft.Owin.Security (v1.0.0) Microsoft.Owin.Security(v1.0.0)
  • Microsoft.Owin.Host.SystemWeb (v3.0.1) Microsoft.Owin.Host.SystemWeb(v3.0.1)
  • Owin (v1.0.0) 奥文(v1.0.0)
  • Microsoft.Owin.Host.SystemWeb (v3.0.1) Microsoft.Owin.Host.SystemWeb(v3.0.1)

Whenever I browse to a controller that requires dependency injection the following error occurs. 每当我浏览到需要依赖注入的控制器时,都会发生以下错误。

 [MissingMethodException: No parameterless constructor defined for this object.]
       System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
       System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +119
       System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232
       System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
       System.Activator.CreateInstance(Type type) +11
       System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +55

    [InvalidOperationException: An error occurred when trying to create a controller of type '_Servicebus.Controllers.AuthenticationController'. Make sure that the controller has a parameterless public constructor.]
       System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +178
       System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +76
       System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +88
       System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +194
       System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +50
       System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +48
       System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
       System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +103
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155 

I believe it has to do with Global.asax.cs and Startup.cs. 我相信它与Global.asax.cs和Startup.cs有关。

Global.asax.cs: 的Global.asax.cs:

 using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Http;
    using System.Web.Mvc;
    using System.Web.Optimization;
    using System.Web.Routing;
    using System.Timers;
    using Microsoft.Practices.Unity;
    using BusinessLayer.HourRegistration.Services;
    using BusinessLayer.HourRegistration.Interfaces;
    using DataAccessLayer.HourRegistration.Repositories;
    using DataAccessLayer.HourRegistration.Entities;
    using System.Data.Entity;
    using System.IO;

    namespace Servicebus
    {
        public class WebApiApplication : System.Web.HttpApplication
        {

            Timer timer;
            bool firsttime;
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                GlobalConfiguration.Configure(WebApiConfig.Register);
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
                /*firsttime = true;
                timer = new Timer();
                timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
                timer.Interval = 20000;
                timer.AutoReset = false;
                timer.Start();*/
            }

            private ICrmUserFilterRepository uService
            {
                get
                {
                    return GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(ICrmUserFilterRepository)) as ICrmUserFilterRepository;
                }
            }

            private IHourRegistrationService hService
            {
                get
                {
                    return GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IHourRegistrationService)) as IHourRegistrationService;
                }
            }

            private void timer_Elapsed(object sender, ElapsedEventArgs e)
            {
                if (firsttime)
                {
                    firsttime = false;
                    timer.Stop();
                    List<CrmUserFilter> tempList = uService.GetAll().ToList();
                    hService.setFourWeeksOldClosed();
                    CrmFetchXml.getCrmFetchXmlInstance.reload24HoursCache(tempList);
                    timer.Interval = GetTimeUntilNextCacheRefresh(2);
                    timer.Start();
                }
                else {
                    timer.Stop();
                    List<CrmUserFilter> tempList = uService.GetAll().ToList();
                    hService.setFourWeeksOldClosed();
                    CrmFetchXml.getCrmFetchXmlInstance.reload24HoursCache(tempList);
                    timer.Interval = GetTimeUntilNextCacheRefresh(2);
                    timer.Start();
                }
            }

            public static double GetTimeUntilNextCacheRefresh(int hour)
            {
                var currentTime = DateTime.Now;
                var desiredTime = new DateTime(DateTime.Now.Year,
                    DateTime.Now.Month, DateTime.Now.Day, hour, 0, 0);
                var timeDifference = (currentTime - desiredTime);
                var timePeriod = currentTime.Hour >= hour ?
                    (desiredTime.AddDays(1) - currentTime) :
                    -timeDifference;
                return Convert.ToInt32(timePeriod.TotalMilliseconds);
            }
        }
    }

Startup.cs: Startup.cs:

  using Microsoft.AspNet.Identity;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Practices.Unity;
using Owin;
using System.Security.Claims;
using System.Web.Helpers;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Unity.WebApi;

[assembly: OwinStartup(typeof(Servicebus.App_Start.Startup))]

namespace Servicebus.App_Start
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }
        public void ConfigureAuth(IAppBuilder app)
        {
            //unity fix
            HttpConfiguration config = new HttpConfiguration();

            UnityContainer container = WebApiConfig.Register(config);

            // ... Configure you web api routes
            config.DependencyResolver = new UnityDependencyResolver(container);

            app.UseWebApi(config);
            //GlobalConfiguration.Configure(config);
            //app.UseWebApi(GlobalConfiguration.DefaultServer);


            // Enable the application to use a cookie to store information for the signed in user
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Authentication/Login")
            });

            //app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
        }
    }
}

WebApiConfig.cs: WebApiConfig.cs:

        using System.Web.Http;
        using Microsoft.Practices.Unity;
        using BusinessLayer.HourRegistration.Interfaces;
        using BusinessLayer.HourRegistration.Services;
        using DataAccessLayer.HourRegistration.Repositories;
        using System.Net.Http.Formatting;
        using System.Data.Entity;
        using Unity.WebApi;
        using System.Web.Mvc;
        using Servicebus.Security;
        using System.Diagnostics;
        using BusinessLayer.MTO.Interfaces;
        using DataAccessLayer.MTO.Repositories.InterfaceRepositories;
        using BusinessLayer.MTO.Services;
        using DataAccessLayer.MTO.Repositories;
        using DataAccessLayer.Common.DatabaseFactory;
        using DataAccessLayer.HourRegistration.UnitOfWork;
        using DataAccessLayer.MTO.UnitOfWork;

        namespace Servicebus
        {
            public static class WebApiConfig
            {
                public static UnityContainer Register(HttpConfiguration config)
                {

                    config.EnableCors();

                    UnityContainer container = new UnityContainer();
container.RegisterType<IAuthenticationService, AuthenticationService>();
                    container.RegisterType<IDatabaseFactory, DatabaseFactory>(new PerResolveLifetimeManager());
                    container.RegisterType<IUnitOfWorkHourregistration, UnitOfWorkHourregistration>();
                    container.RegisterType<ICrmProjectRepository, CrmProjectRepository>();
                    container.RegisterType<ICrmOrderRepository, CrmOrderRepository>();
                    container.RegisterType<IHourRegistrationRepository, HourRegistrationRepository>();
                    container.RegisterType<IOverTimeHoursRepository, OverTimeHoursRepository>();
                    container.RegisterType<IWorkhoursRepository, WorkHoursRepository>();
                    container.RegisterType<IRoleRepository, RoleRepository>();
                    container.RegisterType<IUserRepository, UserRepository>();
                    container.RegisterType<IHourRegistrationService, HourRegistrationService>();
                    container.RegisterType<IRoleProviderService, RoleProviderService>();
                    container.RegisterType<ICrmUserFilterRepository, CrmUserFilterRepository>();

                    //for MTO
                    container.RegisterType<IMTOService, MTOService>();
                    container.RegisterType<IUnitOfWorkMTO, UnitOfWorkMTO>();
                    container.RegisterType<IMtoRepository, MtoRepository>();
                    container.RegisterType<IChapterRepository, ChapterRepository>();
                    container.RegisterType<IQuestionRepository, QuestionRepository>();
                    container.RegisterType<IQuestionKindRepository, QuestionKindRepository>();
                    container.RegisterType<IAnswerRepository, AnswerRepository>();
                    container.RegisterType<IDepartmentRepository, DepartmentRepository>();
                    container.RegisterType<IReportRepository, ReportRepository>();
                    container.RegisterType<IActionPointRepository, ActionPointRepository>();
                    container.RegisterType<IUserMtoRepository, UserMtoRepository>();
                    container.RegisterType<IRoleMtoRepository, RoleMtoRepository>();
                    container.RegisterType<IMtoUserResponseRepository, MtoUserResponseRepository>();

                    config.DependencyResolver = new UnityDependencyResolver(container);
                    config.Formatters.JsonFormatter.MediaTypeMappings.Add(new UriPathExtensionMapping("json", "application/json"));

                    config.Formatters.XmlFormatter.MediaTypeMappings.Add(new UriPathExtensionMapping("xml", "application/xml"));


                    // Web API routes
                    config.MapHttpAttributeRoutes();

                    config.Routes.MapHttpRoute(
                        name: "DefaultApi",
                        routeTemplate: "api/{controller}/{id}",
                        defaults: new { id = RouteParameter.Optional }
                    );
                    config.Routes.MapHttpRoute(
                        name: "Api UriPathExtension",
                        routeTemplate: "api/{controller}.{ext}/{id}",
                        defaults: new { id = RouteParameter.Optional }
                    );
                    config.Routes.MapHttpRoute(
                        name: "MtoApi",
                        routeTemplate: "api/{controller}/{id}",
                        defaults: new { controller = "mto", id = RouteParameter.Optional }
                        );
                    return container;
                }
            }
        }

The services involved indeed do have a parameterless constructor, the controller has one too, the service stays empty. 所涉及的服务确实有一个无参数构造函数,控制器也有一个,服务保持为空。

A random [unfinished] service: 随机[未完成]服务:

using BusinessLayer.Authentication.Interfaces;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BusinessLayer.Authentication.Services
{
    public class AuthenticationService : IAuthenticationService
    {

        public AuthenticationService()
        { }

        public bool CheckRedirects(string applicationName, string jsonString)
        {
            JObject jsonObj = JObject.Parse(jsonString);
            ////Exists? --> Search in JSON.
            foreach (KeyValuePair<string, JToken> sub_obj in (JObject)jsonObj["Redirects"])
            {

            }

            return true;
        }
    }
}

AuthenticationController.cs: AuthenticationController.cs:

using BusinessLayer.Authentication.Interfaces;
using Microsoft.AspNet.Identity;
using Microsoft.Owin.Security;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Cors;
using System.Web.Mvc;

namespace Servicebus.Controllers
{
    [System.Web.Mvc.AllowAnonymous]
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class AuthenticationController : Controller
    {

        /// <summary>
        /// Service from the business layer to get the right information
        /// </summary>
        public IAuthenticationService aService;
        /// <summary>
        /// Constructor of the hourregistation controller gets the service from the unity container.
        /// </summary>

        public AuthenticationController(IAuthenticationService aService)
        {
            this.aService = aService;
        }

        public ActionResult Login()
        {
            NameValueCollection queryString = Request.QueryString;
            aService.CheckRedirects(queryString["applicationType"], System.IO.File.ReadAllText(Server.MapPath(Url.Content("~/Content/loginRedirects.json"))));


            String state = Guid.NewGuid().ToString();
            String url = this.Url.Action("Callback", "Authentication", null, this.Request.Url.Scheme).ToString();
            return Redirect(removed);
        }

        public ActionResult Callback()
        {
            NameValueCollection queryString = Request.QueryString;
            if (!queryString["code"].Equals(null))
            {
                IdentityStore(queryString["code"], queryString["state"]);
            }

            return null;
        }

        private void IdentityStore(string authToken, string queryString, bool isPersistent = false)
        {
            var claims = new List<Claim>();
            claims.Add(new Claim(ClaimTypes.NameIdentifier, authToken));
            claims.Add(new Claim("state", queryString));

            var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);

            AuthenticationManager.SignIn(new AuthenticationProperties()
            {
                AllowRefresh = true,
                IsPersistent = isPersistent,
                ExpiresUtc = DateTime.UtcNow.AddDays(7)
            }, identity);
        }

        private IAuthenticationManager AuthenticationManager
        {
            get
            {
                return HttpContext.GetOwinContext().Authentication;
            }
        }

        public void IdentitySignout()
        {

            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie, DefaultAuthenticationTypes.ExternalCookie);
        }
    }
}

Any help is appreciated. 任何帮助表示赞赏。

Regards! 问候!

Basically, you need to make sure that all your dependencies are registered in the OWIN startup class, because the global won't be used for the WebApi pipeline. 基本上,您需要确保所有依赖项都在OWIN启动类中注册,因为全局不会用于WebApi管道。

You can use shared containers as well for the dependency containers so that you're not initialising two separate instances. 您也可以使用共享容器作为依赖项容器,这样您就不会初始化两个单独的实例。

The quick fix: 快速修复:

namespace Servicebus.App_Start
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            WebApiConfig.Register(new HttpConfiguration());
            ConfigureAuth(app);
        }
    }
}

Unity comes with an activator which Provides the bootstrapping for integrating Unity with WebApi when it is hosted in ASP.NET according to its own documentation. Unity附带了一个激活器, Provides the bootstrapping for integrating Unity with WebApi when it is hosted in ASP.NET根据自己的文档Provides the bootstrapping for integrating Unity with WebApi when it is hosted in ASP.NETProvides the bootstrapping for integrating Unity with WebApi when it is hosted in ASP.NET

This is the nuget: 这是nuget:

<package id="Unity.AspNet.WebApi" version="3.5.1405-prerelease" targetFramework="net45" />

I advise you implement that 我建议你实现它

Important Package 重要包裹

<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net45" />

Have you got this? 你有这个吗?

Final Thoughts 最后的想法

I always find it a good idea to make a small project with just the the infrastructure bits - see if you can get a basic website up and running. 我总是觉得用一个基础设施位做一个小项目是个好主意 - 看看你是否可以启动并运行一个基本网站。 If you can do this then you should be able to debug yourself what the issue is. 如果你能做到这一点,那么你应该能够自己调试问题所在。

If you can't get a simple website running on your machine - try another machine - if all else fails then you have serious problems. 如果你不能在你的机器上运行一个简单的网站 - 尝试另一台机器 - 如果所有其他机器都失败了那么你就会遇到严重问题。 I have got many of these types of projects up and running so it should be straightforward. 我已经启动并运行了许多这类类型的项目,所以它应该是直截了当的。

As it turns out, dependency injection in a regular controller does not work using Unity. 事实证明,常规控制器中的依赖注入不能使用Unity。 Making changes to the controller has resolved the issue. 对控制器进行更改已解决了该问题。

The controller now looks like this: 控制器现在看起来像这样:

        using Microsoft.AspNet.Identity;
        using Microsoft.Owin.Security;
        using Newtonsoft.Json.Linq;
        using System;
        using System.Collections.Generic;
        using System.Collections.Specialized;
        using System.Diagnostics;
        using System.IO;
        using System.Linq;
        using System.Net.Http;
        using System.Security.Claims;
        using System.Threading.Tasks;
        using System.Web;
        using System.Web.Http;
        using System.Web.Http.Cors;
        using System.Web.Mvc;

        namespace Servicebus.Controllers
        {
            [System.Web.Mvc.AllowAnonymous]
            [EnableCors(origins: "*", headers: "*", methods: "*")]
            public class AuthenticationController : Controller
            {

                /// <summary>
                /// Service from the business layer to get the right information
                /// </summary>
                private IAuthenticationService _aService
                {
                    get
                    {
                        return GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IAuthenticationService)) as AuthenticationService;
                    }
                }
                /// <summary>
                /// Constructor of the hourregistation controller gets the service from the unity container.
                /// </summary>
                public AuthenticationController()
                {

                }
//other functions
    }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 依赖注入:没有为此定义无参数构造函数 object - Dependency Injection: No parameterless constructor defined for this object WCF:没有为此对象依赖注入Simple Injector定义的无参数构造函数 - WCF: no parameterless constructor defined for this object dependency injection Simple Injector 没有为此对象定义无参数构造函数 - No parameterless constructor defined for this object 没有为此对象定义无参数构造函数。 当我尝试使用 Unity 依赖时 - No parameterless constructor defined for this object. while i try for Unity Dependency automapper 中没有为此 object 定义无参数构造函数 - No parameterless constructor defined for this object in automapper 错误:未为此对象定义无参数构造函数 - Error: No parameterless constructor defined for this object 在mvc中没有为此对象定义无参数构造函数 - No parameterless constructor defined for this object in mvc MissingMethodException:没有为此对象定义无参数构造函数 - MissingMethodException: no parameterless constructor defined for this object 从数据库更新实体后发生错误:未为此对象定义无参数构造函数 - Error after updating Entity from Database: No parameterless constructor defined for this object 奇怪的错误:没有为此对象定义无参数构造函数 - Strange error: No parameterless constructor defined for this object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM