C#. Разрешение зависимости через DI Autofac, 2 разных объекта на 1 зависимость

213
16 февраля 2018, 16:25

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

public class XmlSerializeTableRecRepository : ITrainTableRecRepository
{
    public XmlSerializeTableRecRepository(string connection)
    {        
    }
    //Members...    
}
public interface ITrainTableRecRepository : IGenericDataRepository<TrainTableRec>
{
}

/// <summary>
/// регистрируем сопоставление типов
/// </summary>
private static void RegisterType(ContainerBuilder builder)
{
   builder.RegisterType<XmlSerializeTableRecRepository>().As<ITrainTableRecRepository>()
          .WithParameters(new List<Parameter> { new NamedParameter("connection", @"TrainTableMain.xml") });
}

Нужно внедрить зависимость от репозитория (IGenericDataRepository). таблица хранится в XML файлах, непосредственная реализация репозитория работает с данными через сериализацию, но возможны другие типы хранилища, для этого и есть ITrainTableRecRepository.

Пока данные хранились в 1 XML файле ("TrainTableMain.xml"), все работало как по учебнику). Но понадобилось параллельно через удаленный HTTP сервис получать данные и складывать их в репозиторий, только в другой ("TrainTableRemoute.xml").

Т.е. нужно чтобы DI создал объекты так для удаленного сервиса:

var rep= new XmlSerializeTableRecRepository("TrainTableRemoute.xml");

для локального сервиса:

var rep= new XmlSerializeTableRecRepository("TrainTableMain.xml");

Но как мне зарегистрировать типы для такого соответствия, если 1 раз уже заданно `ITrainTableRecRepository -> XmlSerializeTableRecRepository("TrainTableMain.xml")?

Или это нарущает основы работы контейнера и придется делать фейковый тип для второго объекта?

Или просто передавать строку подключения через public свойство в сам репозиторий, после его создания через DI?

Answer 1

Используйте именованные сервисы:

builder.RegisterType<XmlSerializeTableRecRepository>()
    .Named<ITrainTableRecRepository>("Main")
    .WithParameter("connection", "TrainTableMain.xml");
builder.RegisterType<XmlSerializeTableRecRepository>()
    .Named<ITrainTableRecRepository>("Remote")
    .WithParameter("connection", "TrainTableRemote.xml");

Но магии, конечно же, не получится: для всех кто использует этот репозиторий вам придется явно указывать какой из репозиториев ему нужен:

builder.RegisterType<Foo>()
    .WithParameter(new ResolvedParameter(
        (pi, ctx) => pi.ParameterType == typeof(ITrainTableRecRepository),
        (pi, ctx) => ctx.ResolveNamed<ITrainTableRecRepository>("Remote")
    ));
Answer 2

Извиняюсь что не понял ответ Pavel Mayorov, сделал вот так.

    //REGISTER
                builder.RegisterType<XmlSerializeTableRecRepository>().Named<ITrainTableRecRepository>("Local")
                    .WithParameters(new List<Parameter> { new NamedParameter("connection", @"TrainTableMain.xml") });

                builder.RegisterType<XmlSerializeTableRecRepository>().Named<ITrainTableRecRepository>("RemoteCis")
                    .WithParameters(new List<Parameter> { new NamedParameter("connection", @"TrainTableRemoteCis.xml") });
    //RESOLVE       
using (var scope = AutofacConfig.Container.BeginLifetimeScope())
                    {
                        var repResolve = scope.ResolveNamed<ITrainTableRecRepository>("Local");
                        var repResolve2 = scope.ResolveNamed<ITrainTableRecRepository>("RemoteCis");
                    }
READ ALSO
Помогите указать ключи

Помогите указать ключи

Дана модель:

173
C# работа с DBF от FoxPRO 2.0

C# работа с DBF от FoxPRO 2.0

В общем такая лабораторная работа: Есть файл DBDBF от FoxPRO 2

274
C# Получение коллекций с вложенными коллекциями из базы MSSQL

C# Получение коллекций с вложенными коллекциями из базы MSSQL

Здравствуйте! Вопрос такой - в своём приложении использую, например, класс подразделения (Department), у которого есть вложенная коллекция сотрудников...

318
Monodevelop.ошибка создания целевого объекта

Monodevelop.ошибка создания целевого объекта

Переношу проект с# window в monodevelopНо выходит ошибка при компиляции ошибка создания целевого объекта LinkEmbeddableAssemblies:

191