2011-08-05 277 views
0

我有一個需要2個構造函數的命令類。但是, 使用structuremap似乎我只能指定一個構造函數來使用 。我現在通過子類型化特定的命令類來解決問題,其中每個實現都實現它自己的接口和構造函數 。就像下面的代碼所示。 ISelectCommand爲 字符串構造函數和int構造函數實現了兩個單獨的接口,僅僅爲了 使用結構映射註冊了這兩個子類型。重載構造映射構造函數

但是,我認爲這是一個黑客,我只是想知道爲什麼它不是 結構映射可以解決由作爲構造函數的參數傳入的 類型的構造函數簽名?然後我可以註冊 SelectProductCommand作爲一個ISelectCommand並且 將它例化爲: ObjectFactury.With(10).Use>(); (「testproduct」)。使用>();

public class SelectProductCommand : ISelectCommand<IProduct>, 
ICommand, IExecutable 
{ 
    private readonly Func<Product, Boolean> _selector; 
    private IEnumerable<IProduct> _resultList; 

    public SelectProductCommand(Func<Product, Boolean> selector) 
    { 
     _selector = selector; 
    } 

    public IEnumerable<IProduct> Result 
    { 
     get { return _resultList; } 
    } 

    public void Execute(GenFormDataContext context) 
    { 
     _resultList = GetProductRepository().Fetch(context, 
_selector); 
    } 

    private Repository<IProduct, Product> GetProductRepository() 
    { 
     return ObjectFactory.GetInstance<Repository<IProduct, 
Product>>(); 
    } 
} 

public class SelectProductIntCommand: SelectProductCommand 
{ 
    public SelectProductIntCommand(Int32 id): base(x => 
x.ProductId == id) {} 
} 

public class SelectProductStringCommand: SelectProductCommand 
{ 
    public SelectProductStringCommand(String name): base(x => 
x.ProductName.Contains(name)) {} 
} 

P.我知道如何告訴結構圖什麼構造函數圖使用,但我的問題是,如果有一種方法讓結構圖根據傳遞給構造函數的參數(即使用常規方法重載)選擇正確的構造函數。

回答

1

我想我用一個小實用工具類解決了這個問題。該類從ObjectFactory獲取具體類型,並使用此類型根據過去的參數構造實例到工廠方法中。現在在'客戶端'我使用ObjectFactory來創建一個CommandFactory的實例。 CommandFactory的實現在另一個解決方案中,因此'客戶端解決方案'仍然獨立於'服務器'解決方案。

public class CommandFactory 
{ 

    public ICommand Create<T>() 
    { 
     return Create<T>(new object[] {}); 
    } 

    public ICommand Create<T>(object arg1) 
    { 
     return Create<T>(new[] {arg1}); 
    } 

    public ICommand Create<T>(object arg1, object arg2) 
    { 
     return Create<T>(new[] {arg1, arg2}); 
    } 

    public ICommand Create<T>(object arg1, object arg2, object arg3) 
    { 
     return Create<T>(new[] {arg1, arg2, arg3}); 
    } 

    public ICommand Create<T>(object[] arguments) 
    { 
     return (ICommand)Activator.CreateInstance(GetRegisteredType<T>(), arguments); 
    } 

    public static Type GetRegisteredType<T>() 
    { 
     return ObjectFactory.Model.DefaultTypeFor(typeof (T)); 
    } 
} 
1

簡短的回答是this post by the creator of Structuremap

長的答案是關於你在那段代碼中的結構。在我看來,命令在定義上是一個「類」,它對某個「實體」做了某些事情,即它以某種方式修改了該類。認爲CreateNewProductCommand。

這裏你使用的是查詢命令,如果我沒有弄錯的話。在這裏浮動的關注問題也有一點分離。發佈的命令定義做什麼和怎麼做的,這是多,你得到的那種服務的位置您使用的是

private Repository<IProduct, Product> GetProductRepository() 
{ 
    return ObjectFactory.GetInstance<Repository<IProduct, Product>>(); 
} 

我會結構中的命令的方法是使用CreateProductCommand作爲數據合同,即只包含產品信息等數據。 然後你有一個CreateProductCommandHandler實現IHandles<CreateProductCommand>與單一的方法HandleExecute。這樣你可以更好地分離關注點和可測試性。

對於查詢的一部分,只需直接用你的repositores在你的控制器/主持人,另外也可以使用Query Object pattern

+0

這裏是讓你在命令/處理程序去一些鏈接: http://lostechies.com/jimmybogard/2010/01/07/advanced-structuremap-custom-registration-conventions-for-partially-關閉類型/ http://lostechies.com/derickbailey/2008/11/20/ptom-command-and-conquer-your-ui-coupling-problems/ – Henning

+0

我很抱歉,但這不是我正在尋找的答案對於。我知道你由傑里米米勒提到的帖子。但正如我所提到的,這隻涉及事先指定一個特定的構造函數。至於你對命令模式的評論,謝謝,我會研究一下。但是,您應該認識到命令類(可能命名不合適)僅僅是從存儲庫中獲取產品的select方法的包裝。我也有插入,刪除和更新命令。這種設置的意圖是,我可以將它們添加到傳遞給事務管理器的命令列表中。 – halcwb