1

我使用的是由溫莎城堡DI容器提供的類型工廠。我對DI容器頗爲陌生,所以在對我的解決方案進行了一些指導之後。溫莎城堡工廠實施

這是我實現:

*更新註冊& DB調用

public interface IAgent { } 
public class Agent : IAgent  { } 

public interface IAgentFactory  
{ 
    IAgent Create(); 
    IAgent Create(int agentId); 
    IAgent Create(AgentDTO agentDTO); 
} 

class AgentFactory : IAgentFactory  
{   
    public IAgent Create()   
    {    
     return InitNewEntity(new Agent()); 
    } 
    public IAgent Create(int agentId, IDBContext dbContext) //Not happy with this, as it's a dependency that isn't factored out :( 
    { 
     return dbContext.GetAgent(agentId); 
    } 
    public IAgent Create(AgentDTO agentDTO) 
    { 
     Agent agent = InitNewEntity(new Agent()); 
     agent.ParseDTO(agentDTO); 
     return agent; 
    } 
    private IAgent InitNewEntity(IAgent agent) 
    { 
     agent.Username = "";  /// + other fields to initialise 
     agent.DOB = DateTime.Now; /// etc. 
     return agent; 
    } 

...

Container.AddFacility<TypedFactoryFacility>() 
      .Register(Component.For<IAgentFactory>() 
           .ImplementedBy<AgentFactory>()); 

這我用下面的調用獲得一些實體

IAgentFactory agentFactory = ViewModel.Container.Resolve<IAgentFactory>(); 

IAgent agent = agentFactory.Create(); //Creates new Agent entity 
agent = agentFactory.Create(66, dbContext); //Looks up entity in database, don't like passing in a db context, another dependency 
agent = agentFactory.Create(agentDTO);  //Creates Agent entity from DTO object 

我對此有幾點擔憂。

有關於創建新代理3所可能出現的情況,

1:從頭

2創建新劑:使用現有的DTO創建一個代理(數據傳輸對象)

3 :通過調用數據庫來創建代理。

我決定將所有這些功能放到工廠中,因爲它似乎符合法案,但是,我不完全確定這是否是完成此操作的正確方法或最佳方法。

問題是,是否可以將所有3個創建方案用於DI容器Register語句並完全省略具體的工廠實現,以便不再有AgentFactory類,而只有IAgentFactory接口。

我有關於這個實現的另一個問題是有可能做一個調用,例如,如果我請求一個Agent實體,Windsor將首先調用工廠並返回從工廠創建的實體,而不是創建沒有引用工廠的實體。 即。

IAgent agent = Container.Resolve<IAgent>(66); 

隨着調用堆棧:

容器 - > AgentFactory - >創建(66) - >返回代理從工廠。

哪個Windsor將攔截並自動使用工廠創建實例。然而,我嘗試過這種方式,並沒有使用工廠來創建它,它只是繼續創建代理而不參考工廠。

我確實有這個,但它沒有調用我定義的工廠方法。

Container.AddFacility<TypedFactoryFacility>() 
      .Register(Component.For<IAgentFactory>().AsFactory(), 
         Component.For<IAgent>().ImplementedBy<Agent>()); 

建議表示感謝,謝謝。

回答

2

鍵入工廠被設計用來創建「行爲」實例,而不是「數據」實例。

您不在容器中註冊一個「模型」組件,但有權使用該模型。 換句話說,您只能在模型中註冊容器。

AgentFactory必須註冊到容器中,但這不是「類型化工廠」。 您可能會將TF用於「晚期依賴」目的。

我更喜歡與我的設計更加分離,並且更加「單一責任性」。 AgentFactory不會在工廠中隱藏存儲庫(按照從數據庫創建的方式):我將改爲將數據讀取器作爲創建參數傳遞。

+0

存儲庫是最後一刻的事情。我認爲,因爲我可以用空構造函數和DTO創建實例,所以我可能會喜歡它查詢數據庫並在可能的情況下檢索實例。 – Craig

+0

使用存儲庫模式AgentyFactory將成爲存儲庫依賴項以創建模型聚合器/實體。在一個sql場景中,倉庫會將一個sqldatareader傳遞給工廠以獲得一個模型實例 – Crixo

+0

我已經將我的倉庫置於一個DI容器的控制之下,只是沒有想過像這樣引用它。爲了將其保存在獨立的庫中,我使用了不同的DI容器。但是,我確定我可以將它考慮進去。我將重新修改示例以便很快表示數據庫引用。 – Craig