StructureMap 配置接口名称不匹配的具体类

发布于 2024-10-04 05:14:41 字数 2045 浏览 0 评论 0原文

不匹配,

Harvester_JohnDeere_Parsley : AbstractMachine, IParsleyHarvester
Harvester_NewHolland_Sage : AbstractMachine, ISageHarvester
Harvester_Kubota_Rosemary : AbstractMachine, IRosemaryHarvester

给定具体类和接口的名称与接口具有公共父级的位置

IParsleyHarvester : ISpiceHarvester
ISageHarvester : ISpiceHarvester
IRosemaryHarvester : ISpiceHarvester

如何配置 StructureMap 以便可以将 I...Harvester 的实例注入到构造函数中,例如

public ParsleyField(IParsleyHarvester parsleyHarvester)

无需在注册表中单独配置每一对?例如,

For<ISageHarvester>().Use<Harvester_NewHolland_Sage>();

我尝试过扫描,

Scan(x =>
{
    x.AssemblyContainingType<Harvester_Kubota_Rosemary>();
    x.AddAllTypesOf<ISpiceHarvester>();

但 I...Harvester 接口未映射。

谢谢!

编辑

两个答案都有效。 @jeroenh 的优点是可以添加保护子句来排除类(无论出于何种原因)。以下是基于 @Mac 对此问题的回答的示例。

public class HarvesterConvention : StructureMap.Graph.IRegistrationConvention
{
    public void Process(Type type, Registry registry)
    {
        // only interested in non abstract concrete types
        if (type.IsAbstract || !type.IsClass)
            return;

        // Get interface
        var interfaceType = type.GetInterface(
            "I" + type.Name.Split('_').Last() + "Harvester");

        if (interfaceType == null)
            throw new ArgumentNullException(
                "type", 
                type.Name+" should implement "+interfaceType);

        // register (can use AddType overload method to create named types
        registry.AddType(interfaceType, type);
    }
}

用法:

Scan(x =>
{
    x.AssemblyContainingType<Harvester_Kubota_Rosemary>();
    x.Convention<HarvesterConvention>();
    x.AddAllTypesOf<ISpiceHarvester>();

Given concrete classes and interfaces having names that don't match

Harvester_JohnDeere_Parsley : AbstractMachine, IParsleyHarvester
Harvester_NewHolland_Sage : AbstractMachine, ISageHarvester
Harvester_Kubota_Rosemary : AbstractMachine, IRosemaryHarvester

where the interfaces have a common parent

IParsleyHarvester : ISpiceHarvester
ISageHarvester : ISpiceHarvester
IRosemaryHarvester : ISpiceHarvester

how can StructureMap be configured so that instances of I...Harvester can be injected into the constructor e.g.

public ParsleyField(IParsleyHarvester parsleyHarvester)

without having to configure each pair individually in the Registry? e.g.

For<ISageHarvester>().Use<Harvester_NewHolland_Sage>();

I've tried scanning

Scan(x =>
{
    x.AssemblyContainingType<Harvester_Kubota_Rosemary>();
    x.AddAllTypesOf<ISpiceHarvester>();

but the I...Harvester interfaces don't get mapped.

Thanks!

edit:

Both answers work. @jeroenh's has the advantage that guard clauses can be added to exclude classes (for whatever reason). Here's an example based on @Mac's answer to this question.

public class HarvesterConvention : StructureMap.Graph.IRegistrationConvention
{
    public void Process(Type type, Registry registry)
    {
        // only interested in non abstract concrete types
        if (type.IsAbstract || !type.IsClass)
            return;

        // Get interface
        var interfaceType = type.GetInterface(
            "I" + type.Name.Split('_').Last() + "Harvester");

        if (interfaceType == null)
            throw new ArgumentNullException(
                "type", 
                type.Name+" should implement "+interfaceType);

        // register (can use AddType overload method to create named types
        registry.AddType(interfaceType, type);
    }
}

usage:

Scan(x =>
{
    x.AssemblyContainingType<Harvester_Kubota_Rosemary>();
    x.Convention<HarvesterConvention>();
    x.AddAllTypesOf<ISpiceHarvester>();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情域 2024-10-11 05:14:41

StructureMap 不知道您的约定。您需要通过添加自定义注册约定来告诉它。实现 IRegistrationConvention 接口,并将约定添加到程序集扫描器中:

Scan(x =>
  {
  x.Convention<MyConvention>();
  }

StructureMap does not know about your convention. You need to tell it about it by adding a custom registration convention. Implement the IRegistrationConvention interface, and add the convention to the assembly scanner:

Scan(x =>
  {
  x.Convention<MyConvention>();
  }
笨死的猪 2024-10-11 05:14:41

我改编了@Kirschstein对这个问题的回答的解决方案。

Scan(x =>
{
    x.AssemblyContainingType<Harvester_Kubota_Rosemary>();
    x.AddAllTypesOf<ISpiceHarvester>()
     .NameBy(type => "I" + type.Name.Split('_').Last() + "Harvester");

定义将具体类的名称转换为其接口名称以供查找的方法。

I adapted a solution from @Kirschstein's answer to this question.

Scan(x =>
{
    x.AssemblyContainingType<Harvester_Kubota_Rosemary>();
    x.AddAllTypesOf<ISpiceHarvester>()
     .NameBy(type => "I" + type.Name.Split('_').Last() + "Harvester");

Defines the way to convert the concrete class's name into its interface name for lookup purposes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文