Мой вопрос выше по-прежнему действителен, но в любом случае вам может помочь следующее.
Funq не поддерживает автоматическое внедрение конструктора (так называемое автоматическое подключение), и вам придется делать это вручную, создавая Func<T>
лямбда-выражения.Поскольку вы уже выполняете инъекцию в конструктор вручную, легко выбрать, что IDbConnectionFactory
вы хотите внедрить в свои сервисы.Пример:
IDbConnectionFactory yellowDbConFactory =
new YellowDbConnectionFactory();
IDbConnectionFactory blueDbConFactory =
new BlueDbConnectionFactory();
IDbConnectionFactory purpleDbConFactory =
new PurpleDbConnectionFactory();
container.Register<IService1>(c =>
new Service1Impl(yellowDbConFactory,
c.Resolve<IDep1>());
container.Register<IService2>(c =>
new Service2Impl(blueDbConFactory);
container.Register<IService3>(c =>
new Service3Impl(purpleDbConFactory,
c.Resolve<IDep2>());
Конечно, вы также можете использовать именованные регистрации, например:
container.Register<IDbConnectionFactory>("yellow",
new YellowDbConnectionFactory());
container.Register<IDbConnectionFactory>("blue",
new BlueDbConnectionFactory());
container.Register<IDbConnectionFactory>("purple",
new PurpleDbConnectionFactory());
container.Register<IService1>(c =>
new Service1Impl(
c.Resolve<IDbConnectionFactory>("yellow"),
c.Resolve<IDep1>());
container.Register<IService2>(c =>
new Service2Impl(
c.Resolve<IDbConnectionFactory>("blue"));
container.Register<IService3>(c =>
new Service3Impl(
c.Resolve<IDbConnectionFactory>("purple"),
c.Resolve<IDep2>());
Из-за отсутствия поддержки автоматического подключения вы получите следующиедовольно неуклюжие регистрации, и это очень скоро приведет к кошмару обслуживания вашего корня композиции, но это не имеет отношения к вашему вопросу; -)
Обычно вы должны попытаться предотвратить двусмысленность в вашей регистрации.В вашем случае у вас есть один интерфейс, который делает две вещи (подключается к двум базам данных).Если обе базы данных не используют одну и ту же модель, каждая база данных заслуживает своего собственного интерфейса (если две реализации не являются взаимозаменяемыми, вы нарушите принцип замены Лискова ):
interface IYellowDbConnectionFactory : IDbConnectionFactory
{
}
interface IPurpleDbConnectionFactory : IDbConnectionFactory
{
}
Из-за того, как работает ServiceStack, вам, вероятно, нужно реализовать реализацию для каждого:
class YellowDbConnectionFactory : OrmLiteConnectionFactory,
IYellowDbConnectionFactory
{
public YellowDbConnectionFactory(string s) : base(s){}
}
class PurpleDbConnectionFactory : OrmLiteConnectionFactory,
IPurpleDbConnectionFactory
{
public YellowDbConnectionFactory(string s) : base(s){}
}
Теперь вам нужно изменить определение своих служб, чтобы использовать определенный интерфейс вместо использования IDbConnectionFactory
:
public class MovieService : RestServiceBase<Movie>
{
private readonly IYellowDbConnectionFactory dbFactory;
public MovieService(IYellowDbConnectionFactory factory)
{
this.dbFactory = factory;
}
}
Обратите внимание, что этот класс теперь использует внедрение конструктора вместо внедрения свойства.Вы можете заставить это работать с внедрением свойства, но обычно лучше пойти с внедрением конструктора.Вот SO вопрос об этом.
С Funq ваша конфигурация будет выглядеть следующим образом:
container.Register<MovieService>(c =>
new MovieService(
c.Resolve<IYellowDbConnectionFactory>());
Эти два новых интерфейса и два класса и изменятся наMovieService
мало что выиграл, потому что Funq не поддерживает автоматическое подключение.Вы будете тем, кто соединяет все вместе вручную.Однако, когда вы переключаетесь на платформу, которая поддерживает поддержку автоматического подключения, эта конструкция позволяет контейнеру без проблем вводить нужные зависимости, потому что нет обсуждения того, что вводить.