使用Ninjects ConstructorArgument时,您可以指定要注入特定参数的确切值.为什么这个值不能为null,或者我怎样才能使它工作?也许这不是你想做的事情,但我想在我的单元测试中使用它.例如:
public class Ninja
{
private readonly IWeapon _weapon;
public Ninja(IWeapon weapon)
{
_weapon = weapon;
}
}
public void SomeFunction()
{
var kernel = new StandardKernel();
var ninja = kernel.Get<Ninja>(new ConstructorArgument("weapon", null));
}
Run Code Online (Sandbox Code Playgroud) 我得到了一些带有扩展方法的静态类,它们使用存储库模式为实体添加"业务逻辑".
现在有时我需要IRepository在这些扩展函数中创建一个新的.
我目前正在通过我正在扩展的对象访问我的Ninject内核来解决它,但它真的很难看:
public static IEnumerable<ISomething> GetSomethings(this IEntity entity)
{
using (var dataContext = entity.kernel.Get<IDataContext>())
return dataContext.Repository<ISomething>().ToList();
}
Run Code Online (Sandbox Code Playgroud)
我还可以创建一个静态构造函数,以某种方式从工厂访问Ninject内核,Ninject 2中是否已有基础结构?
有人知道更好的解决方案吗?有没有人对这种方式有一些意见来实现业务逻辑.
我在Global.aspx中有以下代码
protected override void OnApplicationStarted()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn(Assembly.GetExecutingAssembly());
}
protected override IKernel CreateKernel()
{
return new StandardKernel(new ServiceModule());
}
Run Code Online (Sandbox Code Playgroud)
我还有以下Ninject模块:
internal class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<IProductService>().To<ProductService>().InRequestScope();
}
}
Run Code Online (Sandbox Code Playgroud)
我还有一个基本控制器:
public class BaseController : Controller
{
[Inject]
public IProductService ProductService
{
get;
set;
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码有效.我遇到的问题是我想从基本控制器中删除inject属性,并在Ninject ServiceModule中指定它.换句话说,我如何在ServiceModule中编写绑定规则,告诉Ninject将ProductService注入基本控制器的属性?
如果我删除该属性,我将得到NullReferenceException.
我无法使用ninject定义绑定.
我在标准的ASP.NET WebForms应用程序中.我已经为页面和控件中的Inject依赖项定义了一个http处理程序(Property injection).
这是我想要做的:
我正在创建一个自定义组合框usercontrol.根据组合框中枚举的值,我希望能够在属性中注入一个不同的对象(我想要做的是比这更多的参与,但对此的回答应该足以让我走).
我是Ninject的新手(和DI一般).
我理解内核如何加载模块,到目前为止我编写的代码往往只有一行:
myKernel.Get<MyApp>()
Run Code Online (Sandbox Code Playgroud)
它从我的模块中的绑定构造我需要的一切.如果在初始化之后需要新实例,那么这些由我绑定初始化的工厂负责.到目前为止,工厂已经没有任何ninject依赖项,只需按需创建对象.
现在我已经达到了一个点,我需要考虑初始化后的对象创建,我自己的工厂模式不再削减它.这将是为(远程)客户端支持pub/sub接口.对于我的服务器的每个新连接,我想IClient根据ninject模块中定义的一组绑定创建新实例.这是否意味着我在初始化时传入的工厂必须有自己的内核(或者对主内核的引用)?CommonServiceLocator的功能在哪里.CSL是否必要?
在我走得太远之前,我认为最好在这里询问其他人如何处理这个问题.
我需要指向Ninject绑定中的方法作为构造函数参数的一部分.该类的构造函数如下所示:
MyObject(Func<Populator> param1, TimeSpan time)
Run Code Online (Sandbox Code Playgroud)
我一直在寻找并且无法找到一种方法来绑定Func的委托.这甚至可能吗?Ninject不会让我这样做,因为它期望一个对象作为一个参数,并且不会接受代表.
Bind<IInterface>()
.To<MyObject>()
.InSingletonScope()
.WithConstructorArgument
("param1", ctx => ctx.Kernel.Get<OtherWiredObject>().PopMethod)
.WithConstructorArgument
("time", new TimeSpan(0,30,0));
Run Code Online (Sandbox Code Playgroud)
有没有办法让这种行为在Ninject中起作用?
鉴于:
public interface IBatchProcess
{
void Run();
}
Run Code Online (Sandbox Code Playgroud)
和多个实现:
public class BatchProcessOne : IBatchProcess { ... }
public class BatchProcessTwo : IBatchProcess { ... }
public class BatchProcessThree : IBatchProcess { ... }
Run Code Online (Sandbox Code Playgroud)
和一个跟踪装饰:
public class BatchProcessTraceDecorator : IBatchProcess
{
private readonly IBatchProcess _inner;
public BatchProcessTraceDecorator( IBatchProcess inner )
{
_inner = inner;
}
public void Run()
{
Trace.TraceInformation( "Starting batch process..." );
_inner.Run();
Trace.TraceInformation( "Batch process complete." );
}
}
Run Code Online (Sandbox Code Playgroud)
如何绑定装饰器和所有实现,这样当我调用kernel.GetAll时,我得到3个跟踪装饰器实例,每个实例都有不同的内部批处理过程?
我知道Ninject拦截,并且由于各种原因不希望使用基于代理的解决方案.目前看起来我需要使用IBatchProcess实例的激活策略,以便它们被解析,然后我可以装饰并返回它们但我希望我只是错过了绑定api中的某些东西.
我是Ninject的新手,我想知道内核的范围是否应该是每个应用程序1.那么我应该将内核视为单例吗?
谢谢.
我正在使用MVVM灯并设置绑定如下:
class TestModule:NinjectModule
{
public override void Load()
{
Bind<ICollection<Element>>().To<Collection<Element>>();
Bind<Element>().ToSelf();
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试获取ICollection时,我得到一个包含ONE元素的集合.我期待一个很好的收藏.
var _kernel = new StandardKernel(new TestModule());
var col = _kernel.Get<ICollection<Element>>();
Console.WriteLine("Count={0}", col.Count); //Write "Count=1", Expect "Count=0"
Run Code Online (Sandbox Code Playgroud) 我正在玩Ninject Interception扩展.Ian Davis关于它的博客文章表明,拦截总是基于实际的服务类型,而不是接口.例如,以下代码将无效,因为它IFoo是一个接口:
Kernel.InterceptBefore<IFoo>(f => f.DoSomething(),
i => Console.WriteLine("before"));
Run Code Online (Sandbox Code Playgroud)
当然,接下来的这段代码会只有工作Foo.DoSomething是virtual:
Kernel.InterceptBefore<Foo>(f => f.DoSomething(),
i => Console.WriteLine("before"));
Run Code Online (Sandbox Code Playgroud)
在涉及面向方面的编程时,这似乎是一个非常明显的漏洞.我一直非常认真地对接口进行编程,以便我们可以使用模拟框架来模拟我们的各种服务,但绝大多数实际的方法实现都不是虚拟的.如果一个模拟框架可以生成一个IFoo满足我要求的方法,那么Ninject似乎应该能够.
所以我想我的问题是双重的: