简体   繁体   English

StructureMap:根据具体实例属性值有条件地使用具体类型

[英]StructureMap: conditionally use concrete type based on concrete instance property value

I'm struggling to make StructureMap use one of concrete types sharing a common interface. 我正在努力使StructureMap使用共享公共接口的具体类型之一。 This is further complicated by the fact that all candidate objects are descendants of an intermediate abstract class. 所有候选对象都是中间抽象类的后代,这一事实使情况更加复杂。

public interface ICustomer
{
    string Id { get; }
}

public abstract class CommonCustomer : ICustomer {
    public abstract string Id { get; }
}

// Fallback type if none matched
public class BaseCustomer : CommonCustomer
{
    public override string Id { get; } = "Base";
}

// Concrete type 1
public class AlphaCustomer : CommonCustomer
{
    public override string Id { get; } = "Alpha";
}

// Concrete type 2
public class BravoCustomer : CommonCustomer
{
    public override string Id { get; } = "Bravo";
}

What I tried so far: 到目前为止我尝试过的是:

Scan(x =>
{
    x.TheCallingAssembly();
    x.AddAllTypesOf<ICustomer>();
});

var key = "Alpha";

For<ICustomer>().Use("",
    context => context.GetAllInstances<ICustomer>()
        .FirstOrDefault(x => x.Id == key)).Singleton();
For<ICustomer>().UseIfNone<BaseCustomer>().Singleton();

How can I select a concrete type based on it's string property? 如何根据其字符串属性选择具体类型? And how do I scan through types which do not directly implement ICustomer ? 以及如何浏览未直接实现ICustomer类型?

Sounds like you want to create a factory for instantiating ICustomer . 听起来您想创建一个用于实例化ICustomer的工厂。

public interface ICustomerFactory
{
    ICustomer Create(string key);
}

public class CustomerFactory : ICustomerFactory
{
    private readonly IContainer _container;
    public CustomerFactory(IContainer container)
    {
        _container = container;
    }
    public ICustomer Create(string key) => _container.TryGetInstance<ICustomer>(key);
}

And during configuration of your container naming them: 并在配置容器时对它们进行命名:

var container = new Container(c =>
{
    c.For<ICustomerFactory>().Use<CustomerFactory>();
    c.Scan(x =>
    {
        x.TheCallingAssembly();
        x.AddAllTypesOf(typeof(ICustomer))
            .NameBy(t => ((ICustomer)Activator.CreateInstance(t, new object[0], new object[0])).Id);
    });
});

Usage: 用法:

ICustomerFactory factory;
var customer1 = factory.Create("Alpha");
var customer2 = factory.Create("Bravo");
var customer3 = factory.Create("Base");
var customer4 = factory.Create("NotExisting"); // returns null.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在没有具体实例的情况下使用Reflection来获取Type的静态属性的值 - How can I use Reflection to get the value of a Static Property of a Type without a concrete instance 实例名称不包含具体类型或参数的StructureMap构造函数参数 - StructureMap Constructor arguments without Concrete type or args by instance name 对具体类型的StructureMap容器​​的引用 - Reference to StructureMap container in concrete type StructureMap:如何设置特定的接口具体实例以使用特定的CTOR - StructureMap : How to setup for Specific Concrete Instance of Interface to use particular CTOR 结构图-根据注入依赖项的实例的类型有条件地为接口选择具体类型 - Structure map - Conditionally select a concrete type for an interface based on the type of the instance to which the dependency is injected 使用StructureMap配置具体类的属性 - Configure a Property of a Concrete Class using StructureMap StructureMap:选择嵌套依赖的具体类型 - StructureMap: Choose concrete type of nested dependency 根据结构图中的参数解析混凝土类型 - Resolve concrete type depending on parameter in structuremap 如何避免意外使用具体的单例类型或对其进行单元测试,而不是使用StructureMap对其进行抽象 - How to avoid or UnitTest the accidental use of a concrete singleton type instead of its abstraction with StructureMap 获取实现类型的具体属性 - Get concrete property that implements type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM