2012-10-15 168 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