.net - StructureMap GetAllInstances 在需要多个实例时返回一个实例

标签 .net structuremap structuremap4

我有一个根据命令修改记录的应用程序。我使用 StructureMap 作为我的容器,但它的行为并不符合我的预期。

该应用程序有多个命令来更新某些业务实体。我有许多 FluentValidation 验证器来验证这些命令。有些命令共享相同的字段,我已将其提取到界面中。我已经在这些接口(interface)上实现了一些验证器

//example command
public class MoveCommand
    : IMoveAction, IConfigurationAction
{
    public string Section { get; set; }
    public string Bank { get; set; }
    public string Slot { get; set; }
    public List<Configuration> Configurations { get; set; }
}

//Interfaces
public interface IConfigurationAction
{
    List<Configuration> Configurations { get; set; }
}

public interface IMoveAction
{
    string Section { get; set; }
    string Bank { get; set; }
    string Slot { get; set; }
}

//Validators
public class GameConfigurationValidator
    : AbstractValidator<IConfigurationAction>
{
    public GameConfigurationValidator()
    {
        RuleFor(action => action.Configurations).NotEmpty();
    }
}

public class MoveActionValidator
    : AbstractValidator<IMoveAction>
{
    public MoveActionValidator()
    {
        RuleFor(action => action.Section).NotEmpty();
        RuleFor(action => action.Bank).NotEmpty();
        RuleFor(action => action.Slot).NotEmpty();
    }
}

我正在像这样配置 StructureMap 容器

var container = new StructureMap.Container(cfg =>
{
    cfg.Scan(scanner =>
    {
        scanner.AssemblyContainingType(typeof(Program));  //Everything is in same assembly as Program
        scanner.AddAllTypesOf(typeof(IValidator<>));
    });

});

当我尝试检索 MoveCommand 的验证器时,var validators = container.GetAllInstances<IValidator<MoveCommand>>(); ,我希望获得两个验证器,GameConfigurationValidator 和 MoveActionValidator,但 GetAllInstances 仅返回 GameConfigurationValidator。如果我首先定义 MoveActionValidator,它将返回,但不会返回 GameConfigurationValidator。

使用 GetAllInstances 时,我需要做什么才能获取 MoveCommand 的所有验证器(即 GameConfigurationValidator 和 MoveActionValidator)?

完整示例(需要 StructureMap 和 ServiceStack nuget 包):

using System.Collections.Generic;
using ServiceStack.FluentValidation;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            var container = new StructureMap.Container(cfg =>
            {
                cfg.Scan(scanner =>
                {
                    scanner.AssemblyContainingType(typeof(Program));
                    scanner.AddAllTypesOf(typeof(IValidator<>));
                });

            });

            var stuff = container.WhatDoIHave();
            //IValidator<IConfigurationAction>     ServiceStack.FluentValidation     Transient     ConsoleApplication5.GameConfigurationValidator     (Default)
            //IValidator<IMoveAction>              ServiceStack.FluentValidation     Transient     ConsoleApplication5.MoveActionValidator            (Default)

            var validators = container.GetAllInstances<IValidator<MoveCommand>>();
        }
    }

    public class GameConfigurationValidator
        : AbstractValidator<IConfigurationAction>
    {
        public GameConfigurationValidator()
        {
            RuleFor(action => action.Configurations).NotEmpty();
        }
    }

    public class MoveActionValidator
        : AbstractValidator<IMoveAction>
    {
        public MoveActionValidator()
        {
            RuleFor(action => action.Section).NotEmpty();
            RuleFor(action => action.Bank).NotEmpty();
            RuleFor(action => action.Slot).NotEmpty();
        }
    }

    public interface IConfigurationAction
    {
        List<Configuration> Configurations { get; set; }
    }

    public interface IMoveAction
    {
        string Section { get; set; }
        string Bank { get; set; }
        string Slot { get; set; }
    }

    public class Configuration
    {
        public string Theme { get; set; }
        public decimal Denomination { get; set; }
        public string Par { get; set; }
    }

    public class MoveCommand
        : IMoveAction, IConfigurationAction
    {
        public string Section { get; set; }
        public string Bank { get; set; }
        public string Slot { get; set; }
        public List<Configuration> Configurations { get; set; }
    }
}

最佳答案

你想要

scanner.ConnectImplementationsToTypesClosing(typeof (IValidator<>));

而不是

scanner.AddAllTypesOf(typeof(IValidator<>));

参见Structure Map: Generic Types

关于.net - StructureMap GetAllInstances 在需要多个实例时返回一个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36632176/

相关文章:

c# - 同一类型的多个实例

c# - StructureMap 不扫描当前文件夹中的程序集

c# - 返回值的方法不能传递给异常处理程序

c# - 声明一个总是抛出异常的方法?

c# - 使用 FluentFTP 通过 TLS/SSL 与 FTP 服务器传输时为 "Authentication failed because the remote party has closed the transport stream"

c# - StructureMap 对象重新加载

dependency-injection - DotNetNuke 模块开发 - 使用 StructureMap 的 IoC

c# - 找不到 StructureMap 可插入类型或命名空间

c# - 忽略异常类型 : multiple catch block vs. 类型查询的更好方法