【问题标题】:Injecting multiple matching classes with structuremap使用结构映射注入多个匹配类
【发布时间】:2013-06-17 15:09:50
【问题描述】:
interface IRecipe<T>
{
    ICollection<IIngredient<T>> Ingredients { get; set; }
    T Cook();
}

interface IIngredient<T> {}

public class Cheese : IIngredient<Pizza> {}
public class Tomato : IIngredient<Pizza> {}

public class Egg    : IIngredient<Omlette> {}

我希望当我请求IRecipe&lt;SomeType&gt; 的实例时,StructureMap 会找到IIngredient&lt;SomeType&gt; 的所有实现,并以某种方式将它们注册到Recipe

例如如果我请求接口IRecipe&lt;Pizza&gt;,我将获得具有正确成分的Recipe&lt;Pizza&gt; 的具体实例。

有什么办法可以做到吗?

【问题讨论】:

    标签: c# .net dependency-injection structuremap


    【解决方案1】:

    是的,这可以通过 StructureMap 完成。

    我已将ICollection&lt;IIngredient&lt;T&gt;&gt; Ingredients 设为只读,添加了PizzaOmlette 的具体实现,并扩展了CheeseTomato 以供Recipe 使用

    public class Pizza { }
    public class Omlette { }
    
    public class Recipe<T> : IRecipe<T> where T : class, new()
    {
        private readonly IEnumerable<IIngredient<T>> _ingredients;
        public Recipe(IEnumerable<IIngredient<T>> ingredients)
        {
            _ingredients = ingredients;
        }
        public ICollection<IIngredient<T>> Ingredients 
        { 
            get {  return _ingredients.ToList(); } 
        }
        public T Cook()
        {
            return new T();
        }
    }
    
    public interface IRecipe<T>
    {
        ICollection<IIngredient<T>> Ingredients { get; }
        T Cook();
    }
    
    public interface IIngredient<T> { }
    public class Cheese : IIngredient<Pizza>, IIngredient<Omlette> { }
    public class Tomato : IIngredient<Pizza>, IIngredient<Omlette> { }
    public class Egg : IIngredient<Omlette> { }
    

    报名方法如下

    public StructureMap.IContainer ConfigureStructureMap()
    {
        StructureMap.IContainer structureMap;
    
        StructureMap.Configuration.DSL.Registry registry = 
            new StructureMap.Configuration.DSL.Registry();
    
        registry.Scan(scanner =>
        {
            scanner.TheCallingAssembly();
            scanner.ConnectImplementationsToTypesClosing(typeof(IIngredient<>));
        });
    
        structureMap = new StructureMap.Container(registry);
    
        structureMap.Configure(cfg => 
            cfg.For(typeof(IRecipe<>)).Use(typeof(Recipe<>)));
    
        return structureMap;
    }
    

    还有两种测试方法

    [Test]
    public void StructureMapGetInstance_Pizza_ReturnsTwoIngredients()
    {
        StructureMap.IContainer structureMap = ConfigureStructureMap();
    
        var pizza = structureMap.GetInstance<IRecipe<Pizza>>();
    
        Assert.That(pizza.Ingredients.Count, Is.EqualTo(2));
    }
    
    [Test]
    public void StructureMapGetInstance_Omlette_ReturnsThreeIngredients()
    {
        StructureMap.IContainer structureMap = ConfigureStructureMap();
    
        var omlette = structureMap.GetInstance<IRecipe<Omlette>>();
    
        Assert.That(omlette.Ingredients.Count, Is.EqualTo(3));
    }
    

    【讨论】:

    • 非常感谢。你知道ConnectImplementationsToTypesClosingAddAllTypesOf有什么区别吗?他们似乎都在这里实现了相同的目标。
    • 使用AddAllTypesOf 只为CheeseTomato 注册了IIngredient&lt;T&gt; 的第一个定义(即IIngredient&lt;Pizza&gt;),因此IIngredient&lt;Omlette&gt; 的第二次测试失败,因为只返回了一种成分.我改用ConnectImplementationsToTypesClosing 修复了第二个测试。
    猜你喜欢
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多