我有一个web api应用程序,我想使用 Owin , Oauth 和 Ninject ,所以我有这个配置< / p>
依赖注入器
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控制器:
public class AccountController : BaseController
{
#region ctors
public AccountController()
{
}
[Inject]
public AccountController(INotifier _notifierParam, IAccount _IAccount)
{
Notifier = _notifierParam;
Account = _IAccount;
}
#endregion
}
派生自 BaseController ,它是一个没有构造函数的类。
问题是,当我调用帐户控制器的服务时,我得到了这个例外:
“消息”:“发生错误。”,“ExceptionMessage”:“错误 尝试创建类型的控制器时发生 '的AccountController'。确保控制器具有无参数 公共建设者。“, “ExceptionType”:“System.InvalidOperationException”,“StackTrace”:“à System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage 请求,HttpControllerDescriptor controllerDescriptor,Type controllerType)\ r \nà System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage 请求)\ r \nà System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()”, “的InnerException”:{ “消息”:“发生错误。”, “ExceptionMessage”:“激活INotifier时出错\ r \ n没有匹配的绑定可用,类型不是 自我绑定。\ r \ n激活路径:\ r \ n 4)注入依赖性 INotifier进入参数_notifierParam类型的构造函数 AccountController \ r \ n 3)注入依赖关系AccountController 到NamedScope \ r \ n类型的构造函数的参数resolutionRoot 2)将依赖项NamedScope注入到参数resolutionRoot中 OwinNinjectDependencyResolver类型的构造函数\ r \ n 1)请求 IDependencyResolver \ r \ n \ r \ n建议:\ r \ n 1)确保你有 为INotifier定义了一个绑定。\ r \ n 2)如果绑定是在。中定义的 一个模块,确保模块已加载到内核中。\ r \ n 3)确保您没有意外创建多个内核。\ r \ n 4)如果使用构造函数参数,请确保参数 name与构造函数参数名称匹配。\ r \ n 5)如果您正在使用 自动模块加载,确保搜索路径和过滤器 正确的。\ r \ n”, “ExceptionType”: “Ninject.ActivationException” “StackTrace”:“àNinject.KernelBase.Resolve(IRequest request)\ r \ nNinject.Planning.Targets.Target
1.GetValue(Type service, IContext parent)\r\n à Ninject.Planning.Targets.Target
1.ResolveWithin(IContext parent)\ r \ n
àNinject.Activation.Providers.StandardProvider.GetValue(IContext 上下文,IT目标)\ r \nà Ninject.Activation.Providers.StandardProvider&LT;&GT; c__DisplayClass4.b__2(ITarget 目标)\ 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 \ nNinject.Activation.Context.ResolveInternal(Object 范围)\ r \ nNinject.Activation.Context.Resolve()\ r \nà Ninject.KernelBase&LT;&GT; c__DisplayClass15.b__f(IBinding 绑定)\ r \nà System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()\r\n à System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable
1 来源)\ r \nà Ninject.Web.WebApi.NinjectDependencyScope.GetService(类型 serviceType)\ r \nà System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage 请求,输入controllerType,Func`1&amp;激活者)\ r \nà System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage 请求,HttpControllerDescriptor controllerDescriptor,Type controllerType)“}}
所以我需要知道:
答案 0 :(得分:5)
您正在混合依赖注入方法。您正在使用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);
然后确保您在整个应用程序生命周期内只创建一个内核。您应该只有一个内核的静态实例,并从需要它的任何其他对象引用它。