Почему Unity не может выбрать конструктор String при разрешении класса? - PullRequest
0 голосов
/ 18 января 2020

Я обновил Unity с v4.0.1 до v5.11.3 в (. NET 4.5.2) проекте, который раньше работал нормально, но после обновления я получаю следующее исключение: Resolution failed with error: Failed to select a constructor for System.String

Класс, который я пытаюсь разрешить, имеет конструктор String, и я зарегистрировал его с InjectionConstructor. См. Код ниже:

// Multiple IDbContext registrations happen when the application is initialized
container.RegisterType<IDbContext, AuthenticationContext>(typeof(AuthenticationContext).ToString(), new InjectionConstructor(AppConstants.DatabaseKey));
container.RegisterType<IDbContext, ApplicationContext>(typeof(ApplicationContext).ToString(), new InjectionConstructor(AppConstants.DatabaseKey));

public class DbContextFactory : IDbContextFactory
{
   private readonly IUnityContainer _container;

   public DbContextFactory(IUnityContainer container)
   {
      _container = container;
   }

   public IDbContext CreateDbContext<TDbContext>() where TDbContext : IDbContext
   {
      var key = typeof(TDbContext).ToString();
      return container.Resolve<TDbContext>(key);
   }
}

public class AuthenticationContext : DbContextWrapper
{
   public AuthenticationContext(string connectionString) : base(connectionString)
   {
   }
}

public class DbContextWrapper : IDbContext
{
   public DbContextWrapper(string connectionString)
   {
   }
}

Как следует интерпретировать исключение? Не удалось выбрать конструктор для строки, заставляет меня думать, что регистрация прошла успешно и что он ищет конструктор, который принимает строку, но не может ее найти? Что странно, потому что у моего AuthenticationContext есть только один конструктор, который принимает ... строку!

Я попытался уточнить пример полного кода на dotnetfiddle, но там я получаю исключение «Операция может дестабилизировать среду выполнения» при инициализации UnityContainer. См https://dotnetfiddle.net/xuX57K

1 Ответ

0 голосов
/ 18 января 2020

Итак, новое сообщение об исключении, которое я получил после включения режима отладки через container.EnableDebugDiagnostic();, заставило меня задуматься ... Оно говорит, что я должен сконфигурировать контейнер для предоставления строкового значения для конструктора, что, я уверен, я и сделал. Так что это подразумевает, что на самом деле это даже не рассматривает возможность использования моей регистрации. При отладке регистрации контейнеров я обнаружил, что моя регистрация была там, и это тоже не могло быть проблемой.

Затем я понял, что Unity регистрирует все типы по умолчанию, поэтому он пытается создать экземпляр AuthenticationContext и, следовательно, это не удалось, потому что, когда он использует неявную регистрацию, он не знает, что делать с обязательным строковым параметром.

Ошибка в DbContextFactory, и это исправило ее:

public IDbContext CreateDbContext<TDbContext>() where TDbContext : IDbContext
{
   var key = typeof(TDbContext).ToString();

   // This is wrong because it is trying to resolve AuthenticationContext for a given name.
   // But it should resolve a registration for IDbContext for that name since that is
   // how it was registered!
   // return container.Resolve<TDbContext>(key);

   return container.Resolve<IDbContext>(key);
}
...