2015-08-22 2 views
1

После обновления SimpleInjector с версии 2.8.3 по v3.0.1 он возвращает ошибку при попытке передать строку соединения в конструктор. Это работало хорошо в прошлом, но после обновления что-то не так. Ошибка:SimpleInjector не может вводить строку после обновления

A first chance exception of type 'System.ArgumentException' occurred in SimpleInjector.dll

Additional information: The constructor of type MwmJobUpdateNotifier contains parameter 'connectionString' of type String which can not be used for constructor injection.

Вот где контейнер SimpleInjector сконфигурирован:

public static Container Configure(Container container) 
    { 
     // Force assembly reference so Interfaces load correctly. 
     if (typeof(IJobRepository) != null) 
      container.RegisterAllInterfacesForClassesInAssemblyContaining<JobRepository>(); 

     // Force assembly reference so Interfaces load correctly. 
     if (typeof(IGmcService) != null) 
      container.RegisterAllInterfacesForClassesInAssemblyContaining<GmcService>(); 

     container.Options.AllowOverridingRegistrations = true; 
     container.Register<IMwmJobUpdateNotifier>(() => new MwmJobUpdateNotifier(container.GetInstance<IJobRepository>(), 
      ConfigurationManager.ConnectionStrings["Coordinate_DatabaseEntities"].ConnectionString)); 
     container.Options.AllowOverridingRegistrations = false; 

     MWM.Service.DAL.Config.AGI.AGIIocConfig.Configure(container); 

     return container; 
    } 

Похоже, не нравится, как я передать два параметра в конструктор.

Отредактировано: Исключение вызывается в моем ContainerException классе, где регистрируются все интерфейсы:

public static Container RegisterAllInterfacesForClassesInAssemblyContaining<T>(this Container container, Lifestyle lifestyle = null) where T : class 
    { 
     var assembly = typeof(T).Assembly; 

     var registrations = assembly.GetExportedTypes() 
      .Where(type => type.IsClass && 
       type.GetInterfaces() 
        .Except(type.GetInterfaces().SelectMany(x => x.GetInterfaces())) 
        .Except(type.BaseType.GetInterfaces()) 
        .Any()) 
      .Select(type => new 
      { 
       Services = type.GetInterfaces() 
        .Except(type.GetInterfaces().SelectMany(x => x.GetInterfaces())) 
        .Except(type.BaseType.GetInterfaces()), 
       Implementation = type 
      }); 

     foreach (var registration in registrations) 
     { 
      foreach (var service in registration.Services) 
      { 
       if (registration.Implementation.IsGenericTypeDefinition) 
       { 
        if (lifestyle == null) 
        { 
         container.Register(service.GetGenericTypeDefinition(), registration.Implementation.GetGenericTypeDefinition()); 
        } 
        else 
        { 
         container.Register(service.GetGenericTypeDefinition(), registration.Implementation.GetGenericTypeDefinition(), lifestyle); 
        } 
       } 
       else 
       { 
        if (lifestyle == null) 
         container.Register(service, registration.Implementation); 
        else 
         container.Register(service, registration.Implementation, lifestyle); 
       } 
      } 
     } 

     return container; 
    } 

Исключение захваченной в предпоследнем container.Register(...) вызова.

+0

На какой линии вы получаете это исключение? – Steven

+1

Это не поддерживалось в версии 2. Может быть, почему-то «MwmJobUpdateNotifier» является автоматически подключенным, где он явно не был? – Steven

+0

Я получаю исключение в «conatiner.Register (service, registration.Implementation)». Если я снижу пакеты nuget до версии v2.8.3, я больше не получаю исключение. Я вижу, что в версии для версии v3 эта версия SI более ограничительна. Https://github.com/simpleinjector/SimpleInjector/releases – Rober

ответ

0

У меня такая же проблема, но от того, что я читаю здесь: How do I pass a parameter to the constructor using Simple Injector?

кажется вам/нам придется изменить дизайн так, что значения времени выполнения не являются зависимостями конструкторы.

В моей конкретной ситуации объект является службой базы данных и требуются параметры строки подключения, которые хранятся в файле конфигурации, что делает их значениями времени выполнения из-за разных сред в конвейере выпуска.

Мой проект репозиториев не может получить доступ к конфигурационному файлу напрямую (возможно, мне это показалось, но мне было не по себе), поэтому я ввел adver-зависимый преобразователь зависимостей. Этот объект представляет собой всего лишь оболочку словаря с некоторыми методами управления для добавления, удаления, обновления, слияния и проверки требуемых значений, чтобы каждый объект, зависящий от него, мог проверить, содержит ли он необходимые элементы.

public interface IResolver 
{ 
    void Add<T>(string key, T keyValue); 
    T Resolve<T>(string key); 
    bool ResolvesAll(params string[] keys); 
} 

public sealed class Resolver : IResolver 
{ 
    private Dictionary<string, object> directory; 

    public void Add<T>(string key, T keyValue) 
    { 
     if (directory.ContainsKey(key)) 
      directory[key] = keyValue; 
     else 
      directory.Add(key, keyValue); 
    } 

    public T Resolve<T>(string key) 
    { 
     return directory.ContainsKey(key) ? directory[key] as T : default(T); 
    } 
    public bool ResolvesAll(params string[] keys) 
    { 
     return keys.All(k => directory.ContainsKey(k)); 
    } 

} 

Затем контейнер просто регистрирует распознаватель:

container.RegisterSingleton<IResolver, Resolver>(new Resolver()); 

И зависимые классы получают автоматическую проводку объекта.

public class SomeClass : ISomeClass 
{ 
    private readonly IResolver resolver; 
    public SomeClass(IResolver resolver) 
    { 
     this.resolver = resolver; 
    } 

    public void SomeMethod(string whatever) 
    { 
     if (!resolver.ResolvesAll("fred", "barny", "wilma")) 
      throw new Exception("missing dependencies"); 

     var fred = resolver.Resolve<string>("fred"); 
     SomeOtherMethod(fred, whatever); 
    } 
} 
Смежные вопросы