2016-02-19 22 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。儘管我會接受你的回答,謝謝。 –

相關問題