Я использую Unity в C#. У меня есть интерфейс, который я вызываю IConnectionStringLoader
, у которого есть два производных интерфейса.Регистрация Unity переопределяет друг друга
public interface IConnectionStringLoader
{
string Get();
void Write();
}
public interface IDbConnectionStringLoader : IConnectionStringLoader
{
}
public interface IMetaDataConnectionStringLoader : IConnectionStringLoader
{
}
Она имеет только одну реализацию:
public class ConnectionStringLoader : IDbConnectionStringLoader, IMetaDataConnectionStringLoader
{
private readonly string _connectionStringName;
public ConnectionStringLoader(string connectionStringName)
{
_connectionStringName = connectionStringName;
}
public string Get()
{
var cs = ConfigurationManager.ConnectionStrings[_connectionStringName];
if (cs != null)
{
return cs.ConnectionString;
}
return null;
}
public void Write()
{
Console.WriteLine(_connectionStringName);
}
}
Моя регистрация выглядит следующим образом:
container.RegisterType<IMetaDataConnectionStringLoader, ConnectionStringLoader>(new InjectionConstructor("MetaConnection"));
container.RegisterType<IDbConnectionStringLoader, ConnectionStringLoader>(new InjectionConstructor("DbConnection"));
Точка интерфейсов является то, что я могу вводить различные интерфейсы в моих классах и получите правильную строку соединения для каждой реализации. Но проблема в том, что независимо от того, какая регистрация будет выполнена, последняя перезапишет предыдущую.
var foo = _container.Resolve<IDbConnectionStringLoader>();
var bar = _container.Resolve<IMetaDataConnectionStringLoader>();
foo.Write();
bar.Write();
Выход:
DbConnection
DbConnection
Если я инвертировать порядок регистрации на выходе будет MetaConnection
дважды. Итак, мой вывод заключается в том, что последняя регистрация перезаписывает предыдущую. Однако, если я изменить реализацию в производном классе он работает:
public class SomeOtherConnectionStringLoader : ConnectionStringLoader
{
public ConnectionStringLoaderImpl(string connectionStringName) : base(connectionStringName)
{
}
}
И изменения регистрации:
container.RegisterType<IMetaDataConnectionStringLoader, ConnectionStringLoader>(new InjectionConstructor("MetaConnection"));
container.RegisterType<IDbConnectionStringLoader, SomeOtherConnectionStringLoader >(new InjectionConstructor("DbConnection"));
Теперь все работает, но я не понимаю, почему. Я пробовал разных мастеров по жизни, но с тем же результатом. Я думал, что Unity попытается создать экземпляр ConnectionStringLoader
с «правильным» параметром для инъекций на основе интерфейса, но, похоже, здесь есть какая-то другая логика.
Любые предложения, почему регистрация переписывает друг друга?
Как вы звоните 'Write', хотя он не является частью интерфейса? –
Хорошая находка @YacoubMassad. Я добавил его после того, как я вставил код здесь, чтобы создать простой тест. Это не является частью логики, кроме как доказать, что введена неправильная инъекция. Я отредактирую свой вопрос. Спасибо, что заметили. – smoksnes