2016-04-14 18 views
3

У меня есть приложение, которое изменяет записи на основе команд. Я использую StructureMap в качестве своего контейнера, и он не ведет себя так, как я ожидал.StructureMap GetAllInstances возвращает один экземпляр, когда несколько ожидаемых

Приложение имеет несколько команд для обновления некоторых бизнес-объектов. У меня есть несколько валидаторов FluentValidation для проверки этих команд. Некоторые из команд используют одни и те же поля, которые я вытащил на интерфейсы. Я реализовал несколько валидаторов на этих интерфейсах

//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.

Что мне нужно сделать, чтобы иметь возможность получить все валидаторы для MoveCommand при использовании GetAllInstances, то есть как 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; } 
    } 
} 

ответ

2

вы хотите

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

вместо

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

см Structure Map: Generic Types

+0

Благодаря этим S проблема. Вы знаете, какой лучший способ отладки регистрации StructureMap? В настоящее время я полагаюсь на IContainer.WhatDoIHave, чтобы получить отчет о зарегистрированных вещах, но я получаю тот же отчет, используя ли 'ConnectImplementationsToTypesClosing' или' AddAllTypesOf' –

 Смежные вопросы

  • Нет связанных вопросов^_^