【发布时间】:2016-09-12 08:54:12
【问题描述】:
我有一个 web api 应用程序,我想在其中使用 Owin、Oauth 和 Ninject ,所以我有这个配置
依赖注入器
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,这是一个没有构造函数的类。
问题是当我调用帐户控制器的服务时,我得到了这个异常:
"Message":"发生错误。", "ExceptionMessage":"错误 尝试创建类型控制器时发生 '帐户控制器'。确保控制器具有无参数 公共构造函数。", "ExceptionType":"System.InvalidOperationException", "StackTrace":"à System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage 请求,HttpControllerDescriptor 控制器描述符,类型 控制器类型)\r\n à System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage 请求)\r\n à System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()", “内部异常”:{ "Message":"发生错误。", "ExceptionMessage":"激活 INotifier 时出错\r\n没有匹配的绑定可用,并且类型不是 自绑定。\r\n激活路径:\r\n 4) 依赖注入 INotifier 转换为类型构造函数的参数 _notifierParam AccountController\r\n 3) 注入依赖AccountController 进入 NamedScope 类型的构造函数的参数 resolutionRoot\r\n 2)将依赖NamedScope注入参数resolveRoot的 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 请求)\r\n à Ninject.Planning.Targets.Target
1.GetValue(Type service, IContext parent)\r\n à Ninject.Planning.Targets.Target1.ResolveWithin(IContext parent)\r\n
à Ninject.Activation.Providers.StandardProvider.GetValue(IContext 上下文,ITarget 目标)\r\n à Ninject.Activation.Providers.StandardProvider.c__DisplayClass4.b__2(ITarget 目标)\r\n à System.Linq.Enumerable.WhereSelectArrayIterator2.MoveNext()\r\n à System.Linq.Buffer1..ctor(IEnumerable1 source)\r\n à System.Linq.Enumerable.ToArray[TSource](IEnumerable1 源)\r\n à Ninject.Activation.Providers.StandardProvider.Create(IContext 上下文)\r\n à Ninject.Activation.Context.ResolveInternal(对象 范围)\r\n à Ninject.Activation.Context.Resolve()\r\n à Ninject.KernelBase.c__DisplayClass15.b__f(IBinding 绑定)\r\n à System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()\r\n à System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable1 源)\r\n à Ninject.Web.WebApi.NinjectDependencyScope.GetService(类型 服务类型)\r\n à System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)\r\n à System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage 请求,HttpControllerDescriptor 控制器描述符,类型 控制器类型)"} }
所以我需要知道:
- 这个错误的原因是什么?
- 我该如何解决?
【问题讨论】:
-
检查
Notifier类。错误消息指出Error activating INotifier -
还有你如何设置你的依赖解析器。
-
您是否浏览过异常消息中的所有建议。我相信它清楚地告诉你需要检查什么来解决你的问题。注意到另一个示例
Ensure you have not accidentally created more than one kernel.我看到两个实例,您创建了一个新的kernel -
@Nkosi 请看我的编辑
标签: c# .net asp.net-web-api ninject owin