2012-10-15 98 views
0

我有一個場景,我不知道如何最好地解決與城堡。我正在嘗試根據從外部系統檢索到的ID來解析類型。棘手的部分是多個id與相同的具體類型有關。城堡溫莎配置工廠

這是我到目前爲止提出的。這只是感覺有點不對。我不喜歡我需要調用ResolveAll的事實。

[TestFixture] 
public class TestWindsor 
{ 

    [Test] 
    public void AddGreenResolverToContainer_ShouldResolveCorrectTypeAndTypeId() 
    { 
     //---------------Set up test pack------------------- 
     IWindsorContainer container = new WindsorContainer(); 
     //---------------Assert Precondition---------------- 

     //---------------Execute Test ---------------------- 
     container.Register(Component.For<IResolver>() 
           .ImplementedBy<TestOneResolver>() 
           .DependsOn(new {typeId = "1"})); 
     //---------------Test Result ----------------------- 
     var actual = container.Resolve<IResolver>(); 
     Assert.IsInstanceOf<TestOneResolver>(actual); 
     Assert.AreEqual("1", actual.typeId); 
    } 

    [Test] 
    public void AddTwoNamedGreenResolverToContainer_ShouldResolveTwoTypes() 
    { 
     //---------------Set up test pack------------------- 
     IWindsorContainer container = new WindsorContainer(); 
     //---------------Assert Precondition---------------- 

     //---------------Execute Test ---------------------- 
     container.Register(Component.For<IResolver>() 
           .ImplementedBy<TestOneResolver>() 
           .DependsOn(new {typeId = "1"}).Named("tageventstatusresolver")); 
     container.Register(Component.For<IResolver>() 
           .ImplementedBy<TestOneResolver>() 
           .DependsOn(new {typeId = "2"}).Named("second"));    
     container.Register(Component.For<IResolver>() 
           .ImplementedBy<TestTwoResolver>() 
           .DependsOn(new {typeId = "1122"}).Named("redFirst")); 
     container.Register(Component.For<IResolverFactory>() 
            .ImplementedBy<ResolverFactory>() 
            .DependsOn(new { resolvers=container.ResolveAll<IResolver>()})); 


     //---------------Test Result ----------------------- 
     var actual = container.Resolve<IResolverFactory>(); 
     var resolver = actual.Create("1"); 
     Assert.IsInstanceOf<TestOneResolver>(resolver); 
    } 

} 


public interface IResolverFactory 
{ 
    IResolver Create(string typeId); 
} 

public class ResolverFactory : IResolverFactory 
{ 
    private readonly IResolver[] _resolvers; 

    public ResolverFactory(IResolver[] resolvers) 
    { 
     _resolvers = resolvers; 
    } 

    public IResolver Create(string typeId) 
    { 
     return _resolvers.Where(resolver => resolver.typeId == typeId).FirstOrDefault(); 
    } 
} 

public enum ResolutionStatus 
{ 
    Red, 
    Green, 
    Amber 
} 

public interface IResolver 
{ 
    string typeId { get; } 
    ResolutionStatus Resolve(); 
} 

public class TestOneResolver : IResolver 
{ 
    public TestOneResolver(string typeId) 
    { 
     this.TypeId = typeId; 
    } 

    public string TypeId { get; private set; } 

    public ResolutionStatus Resolve() 
    { 
     return ResolutionStatus.Green; 
    } 
} 

public class TestTwoResolver : IResolver 
{ 
    public TestTwoResolver(string typeId) 
    { 
     TypeId = typeId; 
    } 

    public string TypeId { get; private set; } 

    public ResolutionStatus Resolve() 
    { 
     return ResolutionStatus.Red; 
    } 
} 

有沒有人有更好的方法來做到這一點的建議?

+0

你可以發佈你想出的解決方案作爲另一個答案嗎?肯定會對別人有所幫助 – workabyte

+0

很久以前,我在這個項目上工作過。我會回頭看看我到底做了些什麼。 – Andrew

回答

0

將組件名稱設置爲typeId值,並按照this approach的說明創建按類型名稱創建的類型化工廠。

+0

這會工作,但最後你會得到一個硬編碼的枚舉,我將不得不爲每個新類型添加一個新的開關。我已經想通過註冊一個CollectionResolver作爲一個SubResolver和改變工廠採取IEnumeralbe 我可以注入所有的解析器,而不用調用ResolveAll這是我不舒服的部分。 – Andrew

+0

按照枚舉選項命名組件,您不需要任何開關。你輸入的工廠將有一個方法(我的示例中的GetById)返回一個特定的組件。 – Crixo