简单案例:我有一个用于记录消息的接口,如下所示:
public interface ILogger
{
void Log(string message);
}
Run Code Online (Sandbox Code Playgroud)
也许有三个不同的类实现了这个接口.
现在,我可以在一个地方写一行,换行,比如:
kernel.Bind<ILogger>().To<ConsoleLogger>();
Run Code Online (Sandbox Code Playgroud)
我的问题是,如何在许多类中使用该接口,但不通过构造函数注入每个人.因为我们可以使用这么多不同的接口,并且该类构造函数的声明可能很混乱.
我有一个ASP.NET MVC应用程序,我刚刚开始使用ServiceStack的Redis客户端.我使用Ninject作为我的IoC容器.目前我的绑定看起来像这样:
Bind<IRedisClientsManager>()
.ToMethod(c => new BasicRedisClientManager("localhost:6379"))
.InSingletonScope();
Bind<ICacheClient>().ToMethod(c => c.Kernel.Get<IRedisClientsManager>().GetCacheClient());
Bind<IRedisClient>().ToMethod(c => c.Kernel.Get<IRedisClientsManager>().GetClient());
Run Code Online (Sandbox Code Playgroud)
我正在app启动时有效地创建一个BasicRedisClientManager的单例实例,用于在ICacheClient或IRedisClient的任何请求中实例化.我在这里做的是否正确用于典型用例?提前致谢!
我有一个简单的控制台应用程序使用Ninject,Ninject.Logging和Ninject.Extensions.NLog2都使用最新的nuget包构建.
我的应用程序执行以下操作
_kernel = new StandardKernel();
ILogger logger = _kernel.Get<ILogger>();
Run Code Online (Sandbox Code Playgroud)
我StandardKernel在调用时从内部获得Null Reference异常Get<ILogger>()
System.NullReferenceException was unhandled by user code
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=Ninject.Extensions.Logging
StackTrace:
at Ninject.Extensions.Logging.LoggerFactoryBase.GetLogger(IContext context) in c:\Projects\Ninject\ninject.extensions.logging\src\Ninject.Extensions.Logging\LoggerFactoryBase.cs:line 61
at Ninject.Extensions.Logging.LoggerModuleBase.<Load>b__0(IContext context) in c:\Projects\Ninject\ninject.extensions.logging\src\Ninject.Extensions.Logging\LoggerModuleBase.cs:line 26
at Ninject.Activation.Providers.CallbackProvider`1.CreateInstance(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\CallbackProvider.cs:line 45
at Ninject.Activation.Provider`1.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Provider.cs:line 38
at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157
at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, IParameter[] …Run Code Online (Sandbox Code Playgroud) 我了解Ninject的某些功能,并且已经能够将其用于IoC。
当我使用NuGet将对Ninject的引用添加到VS2010中的项目中时,我会在列表中看到其他Ninject扩展。特别是Ninject.MVC3。同样在Ninject网站上的扩展名(http://www.ninject.org/extensions.html)上,我看到了Ninject.Web.Mvc。
如果我正在创建MVC3应用程序,是否需要使用Ninject的此扩展?我对Noject for IoC的类/接口的基本使用是否需要标准库以外的内容?
MVC3项目中的Ninject和Ninject.MVC3 / Ninject.Web.Mvc有什么区别?
我的项目中有一个Web服务,用于将json数据返回给ajax调用.
注入我的ClientService在常规页面上工作正常,但如何让它在Web服务中工作?
NinjectWebCommon.cs:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IClientService>().To<ClientService>();
}
Run Code Online (Sandbox Code Playgroud)
Default.aspx.cs:有效!
public partial class _Default : System.Web.UI.Page
{
[Inject]
public IClientService clientService { get; set; }
Run Code Online (Sandbox Code Playgroud)
MyWebservice.asmx:NullReferenceException(clientService为null)
public class MyWebService: System.Web.Services.WebService
{
[Inject]
public IClientService clientService { get; set; }
[WebMethod, ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public MyObject GetClients(int id)
{
var list = clientService.GetClients(id);
Run Code Online (Sandbox Code Playgroud) 我正在使用Ninject.MVC3和WebAPI.最初,我正在使用这里概述的NinjectResolver和NinjectScope的实现,即使用,我注意到每次调用Controller时都会调用BeginBlock().在对控制器进行负载测试(超过几百次调用)时,我注意到w3wp的内存消耗显着增加(高负载时高达1.4 gigs)并且GC永远不会回收任何内存._kernel.BeginBlock()
根据这篇SO帖子,不应该处理内核并且不应该使用BeginBlock().之后我更新了Resolver和Scope,如下所示:
public class NinjectScope : IDependencyScope
{
protected IResolutionRoot resolutionRoot;
public NinjectScope(IResolutionRoot kernel)
{
resolutionRoot = kernel;
}
public object GetService(Type serviceType)
{
IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
return resolutionRoot.Resolve(request).SingleOrDefault();
}
public IEnumerable<object> GetServices(Type serviceType)
{
IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
return resolutionRoot.Resolve(request).ToList();
}
public void Dispose()
{
//Don't dispose the kernel
//IDisposable disposable = (IDisposable)resolutionRoot;
//if …Run Code Online (Sandbox Code Playgroud) 我将Nuget包Ninject.Web.WebApi从3.2.3更新到3.2.4.更新后,GlobalConfiguration不再包含Configure功能.这样,Global.asax.cs中的以下代码不再起作用:
GlobalConfiguration.Configure(WebApiConfig.Register);
Run Code Online (Sandbox Code Playgroud)
我尝试了以下方法:
WebApiConfig.Register(GlobalConfiguration.Configuration);
Run Code Online (Sandbox Code Playgroud)
但那没用.
有任何想法吗?
编辑:
通过nuget安装更新后,它从packages.config中删除以下两个条目:
<package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net451" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net451" />
Run Code Online (Sandbox Code Playgroud)
在csproj文件中,它删除了对System.Web.Http.WebHost的引用.
在我添加它们之后,项目编译,但WebApi控制器不起作用,因为Ninject没有注入参数.错误是:
尝试创建"HomeController"类型的控制器时发生错误.确保控制器具有无参数的公共构造函数.
在最新更新中有什么根本改变了吗?
当我遇到这个问题时,我正在观看Pluralsight 的教程:搜索这个网站并发现(简单的注入器无法在Web API控制器中注入依赖关系,确保控制器具有无参数的公共构造函数错误)不同的解决方案,但他们没有工作要么.使用WebApi和Ninject时遇到同样的问题,作者在编写代码时没有做任何事情,不知道为什么我要面对这个问题,如果有人解释原因以及解决方案(写什么和写什么),将会很感激.这是代码:
//NinjectWebCommon.cs
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IRepository>().To<Repository>().InRequestScope(); //for making singleton
kernel.Bind<WebAPIandEFContext>().To<WebAPIandEFContext>().InRequestScope();
}
//Order Controller
public class OrderController : ApiController
{
private IRepository _repo;
public OrderController(IRepository repo)
{
_repo = repo;
}
//remaining code....
ERROR description
{"$id":"1","Message":"An error has occurred.","ExceptionMessage":"An error
occurred when trying to create a controller of type 'OrderController'. 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 …Run Code Online (Sandbox Code Playgroud) 我有许多类型,构造函数采用ICommand参数,如下所示:
public AboutCommandMenuItem(ICommand command)
: base(command)
{
}
Run Code Online (Sandbox Code Playgroud)
public OptionsCommandMenuItem(ICommand command)
: base(command)
{
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Ninject,我的ICommand接口配置如下:
_kernel.Bind<ICommand>().To<AboutCommand>().WhenInjectedExactlyInto<AboutCommandMenuItem>();
_kernel.Bind<ICommand>().To<OptionsCommand>().WhenInjectedExactlyInto<OptionsCommandMenuItem>();
Run Code Online (Sandbox Code Playgroud)
有没有办法设置一个约定,以便我可以将ICommand接口绑定到XxxxCommand它注入的时间XxxxCommandMenuItem,并避免必须手动配置接口可以注入的每种可能的类型?
我试过BindToSelection但是选择器表达式没有捕获我注入的类型,而且BindToRegex似乎只是一个字符串类型的选择器.
这是我能得到的最接近的:
_kernel.Bind(t => t.FromThisAssembly()
.SelectAllClasses()
.InNamespaceOf<ICommand>()
.EndingWith("Command")
.Where(type => type.GetInterfaces().Contains(typeof(ICommand)))
.BindAllInterfaces()
.Configure(binding => binding
.When(request => request.Service == typeof(ICommand)
&& request.Target.Member.DeclaringType.Name.StartsWith(?)));
Run Code Online (Sandbox Code Playgroud)
?选择用于绑定的类的名称在哪里?
我是否坚持使用显式绑定?
加载控制器时出现此错误。
An error occurred when trying to create a controller of type 'MembersController'. Make sure that the controller has a parameterless public constructor.
Run Code Online (Sandbox Code Playgroud)
我已经添加了
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new Ninject.WebApi.DependencyResolver.NinjectDependencyResolver(kernel);
Run Code Online (Sandbox Code Playgroud)
NinjectWebCommon注册绑定后转到类。
并且我已经注册了相关服务。见编辑
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IMembersService, MembersService>();
kernel.Bind<MemberContext, MemberContext>();
}
Run Code Online (Sandbox Code Playgroud)
这是我添加的ninject软件包-
<package id="Ninject" version="3.2.0.0" targetFramework="net451" />
<package id="Ninject.MVC5" version="3.2.1.0" targetFramework="net451" />
<package id="Ninject.Web.Common" version="3.2.0.0" targetFramework="net451" />
<package id="Ninject.Web.Common.WebHost" version="3.2.0.0" targetFramework="net451" />
<package id="Ninject.Web.WebApi" version="3.2.4.0" targetFramework="net451" />
<package id="Ninject.WebApi.DependencyResolver" version="0.1.4758.24814" targetFramework="net451" />
Run Code Online (Sandbox Code Playgroud)
我想念什么?
编辑
多亏了与Jerrod Horton(下)的交谈,我才意识到我做错了装订。
本来应该
private …Run Code Online (Sandbox Code Playgroud) c# dependency-injection ninject asp.net-web-api asp.net-web-api2