2016-02-19 30 views
1

我有一个接受依赖作为构造函数参数的类。这个类可能会被其他一些类继承,并且由于技术原因(关于构造函数的顺序等),我必须使用工厂方法和使用Activator.CreateInstance的动态调用。工厂方法不纯粹是基础设施,但它内部有一些初始化逻辑。如何让Ninject在保留解析过程的同时使用特定类型的自定义构造逻辑?

public class Foo { 
    protected Foo(IService service, IOtherService otherService) { ... } 
    ... 
    public Foo Create(Type fooType, params object[] constructorArgs) { 
    var instance (Foo)Activator.CreateInstance(fooType, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance, constructorArgs, null, null); // or something similar... 
    instance.SetDefaultValues(); // for example... 
    instance.StartChangeNotifications(); 
    return instance; 
} 

可能的后代可以采取更多的依赖性等。我想仍然使用Ninject来解决依赖关系并创建对象树。

但是,使用ToMethod绑定我必须创建自己的整个子树。有什么办法可以在解析过程中自定义只有特定类型的构造

我想这样使用它。

kernel.Bind<ConcreteFoo>().ConstructWith(ctx => Foo.Create(ctx.Request.Service, ctx.Arguments)); 

其中ConstructWithctx.Arguments都是虚构的部分。我希望我的问题清楚。

+0

你为什么坚定的关于使用'Activator.CreateInstance'? ninject不能做什么?请注意,有很多方法来参数化ninject的分解/构造,比如'ToConstructor'绑定或'WithConstructorArgument'扩展...... – BatteryBackupUnit

+0

我正在使用它,因为我在工厂方法中有其他的东西,我刚刚省略了它们明晰。我用一些示例行更新了我的帖子。工厂方法中有逻辑,它不仅是基础代码。我知道有很多方法可以将参数传递给解析,但我需要一个不同的东西。 –

+0

使用'ToMethod',你仍然使用'IContext'来创建依赖关系。使用'OnActivation'你可以完成初始化的东西,比如'SetDefaultValues' ...,然后还有'ToConstructor'来选择构造函数并指定要注入的内容。 – BatteryBackupUnit

回答

2

这是你的选择(有一些例子):

  • ToMethod(ctx => Foo.Create(ctx.Kernel.Get<IDependency>())
  • ToConstructor(s => new Foo(s.Inject<IDependency1>(), s.Inject<IDependency2>())
  • WithConstructorArgument(typeof(string), "someParameter")仅指定一个参数,并使用默认分辨率为休息(或其他,自定义,paremeters)
  • OnActivation(o => o.SetDefaultValues())执行后激活逻辑,如SetDefaultValues
  • 或者:OnActivation((IContext ctx, Foo instance) => foo.Initialize(ctx.Kernel.Get<Settings>()))
+0

问题是我想有一个集中式工厂方法,接受动态参数量。每个后代类都可以有自己的参数,所以我需要定义很多单独的绑定,甚至不能使用像约定扩展那样的东西。最接近我的需求的是'OnActivation'回调函数,但是我不喜欢它,因为我把太多的逻辑委托给Ninject,而不是仅仅基础设施的IMO。尽管我会接受你的回答,谢谢。 –

相关问题