gpt4 book ai didi

c# - 使用 owin 和 ninject 的 webapi 应用程序中的无参数构造函数问题

转载 作者:行者123 更新时间:2023-12-03 19:38:43 27 4
gpt4 key购买 nike

我有一个 Web api 应用程序,我想在其中使用 OwinOauthNinject ,所以我有这个配置

依赖注入(inject)器

public class NinjectDependencyResolver : IDependencyResolver
{
private static IKernel kernel;

public NinjectDependencyResolver()
{
kernel = new StandardKernel();
// AddBindings();
}

public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}

public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}

private static void AddBindings()
{
kernel.Bind<INotifier>().To<Notifier>();
kernel.Bind<IEventRepository>().To<EventRepository>();
kernel.Bind<ICrud<Config>>().To<CrudConfig>();
kernel.Bind<ICrud<Evenement>>().To<CrudEvent>();
kernel.Bind<IAccount>().To<Account>();
}



public static Lazy<IKernel> CreateKernel = new Lazy<IKernel>(() =>
{
//var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
AddBindings();

return kernel;
});


}

启动类

public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }

// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public static void ConfigureAuth(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};

// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);

//app.UseNinjectMiddleware(CreateKernel);
}

public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseNinjectMiddleware(() => NinjectDependencyResolver.CreateKernel.Value);
app.UseNinjectWebApi(config);
ConfigureAuth(app);
}
}

Global.cs

 protected void Application_Start()
{
DependencyResolver.SetResolver(new NinjectDependencyResolver());
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}

我也有这门课

 public static class NinjectWebCommon 
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();

/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}

/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}

/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

RegisterServices(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}

/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
}
}

我有这个 api Controller :

public class AccountController : BaseController
{
#region ctors

public AccountController()
{

}
[Inject]
public AccountController(INotifier _notifierParam, IAccount _IAccount)
{
Notifier = _notifierParam;
Account = _IAccount;
}

#endregion
}

它派生自BaseController,它是一个没有构造函数的类。

问题是当我调用帐户 Controller 的服务时,我收到此异常:

"Message":"An error has occurred.", "ExceptionMessage":"An error occurred when trying to create a controller of type 'AccountController'. Make sure that the controller has a parameterless public constructor.", "ExceptionType":"System.InvalidOperationException", "StackTrace":" à System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n à System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n à System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()", "InnerException":{ "Message":"An error has occurred.", "ExceptionMessage":"Error activating INotifier\r\nNo matching bindings are available, and the type is not self-bindable.\r\nActivation path:\r\n 4) Injection of dependency INotifier into parameter _notifierParam of constructor of type AccountController\r\n 3) Injection of dependency AccountController into parameter resolutionRoot of constructor of type NamedScope\r\n 2) Injection of dependency NamedScope into parameter resolutionRoot of constructor of type OwinNinjectDependencyResolver\r\n 1) Request for IDependencyResolver\r\n\r\nSuggestions:\r\n 1) Ensure that you have defined a binding for INotifier.\r\n 2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.\r\n 3) Ensure you have not accidentally created more than one kernel.\r\n 4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.\r\n 5) If you are using automatic module loading, ensure the search path and filters are correct.\r\n", "ExceptionType":"Ninject.ActivationException", "StackTrace":" à Ninject.KernelBase.Resolve(IRequest request)\r\n à Ninject.Planning.Targets.Target1.GetValue(Type
service, IContext parent)\r\n à
Ninject.Planning.Targets.Target
1.ResolveWithin(IContext parent)\r\n
à Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target)\r\n à Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.b__2(ITarget target)\r\n à System.Linq.Enumerable.WhereSelectArrayIterator2.MoveNext()\r\n à
System.Linq.Buffer
1..ctor(IEnumerable1 source)\r\n à
System.Linq.Enumerable.ToArray[TSource](IEnumerable
1 source)\r\n à Ninject.Activation.Providers.StandardProvider.Create(IContext context)\r\n à Ninject.Activation.Context.ResolveInternal(Object scope)\r\n à Ninject.Activation.Context.Resolve()\r\n à Ninject.KernelBase.<>c__DisplayClass15.b__f(IBinding binding)\r\n à System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()\r\n
à System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable
1 source)\r\n à Ninject.Web.WebApi.NinjectDependencyScope.GetService(Type serviceType)\r\n à System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n à System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"} }

所以我需要知道:

  1. 此错误的原因是什么?
  2. 我该如何修复它?

最佳答案

您正在混合依赖注入(inject)方法。您正在使用 OWIN 设置 Web API 的 ninject 中间件,但随后您在 OWIN 之外管理 Web API(使用 IIS 管道):

protected void Application_Start()
{
//..
GlobalConfiguration.Configure(WebApiConfig.Register);
//..
}

第二个错误是您正在创建多个内核,并且您的异常消息警告您避免这种情况:

Ensure you have not accidentally created more than one kernel

首先重构您的代码。仅使用 OWIN 管理 Web API:

public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseNinjectMiddleware(() => NinjectDependencyResolver.CreateKernel.Value);
ConfigureAuth(app);
app.UseNinjectWebApi(config);
}

并从Global.asax.cs中删除此行:

GlobalConfiguration.Configure(WebApiConfig.Register);

然后确保您在整个应用程序生命周期中仅创建一个内核。您应该只有一个内核的静态实例,并从需要它的任何其他对象引用它。

关于c# - 使用 owin 和 ninject 的 webapi 应用程序中的无参数构造函数问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37256087/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com