Мое приложение имеет дело с несколькими клиентами, и каждый клиент имеет разные настройки. Итак, я решил использовать контейнер IOC для регистрации каждого конкретного клиента с помощью key
. Затем я устанавливаю ClientSettings на основе key
. Значение key
будет доступно во время выполнения.Как написать библиотеку классов C# IOC и ServiceLocator?
C# библиотека MyCompany.BO
public class ClientSettings : IClientSettings
{
public string ClientApiKey { get; private set}
public string ClientId { get; private set}
public static IClientSettings Load(string clientname)
{
// Load the client specific information from JSON file using clientname
var cs = new ClientSettings();
cs.ClientApiKey = "Some client specific key";
cs.ClientId = "Some client specific key";
return cs;
}
}
Потребляемый в MyCompany.BO имен
public class RuleEngine : IRuleEngine
{
IFactory _factory;
RuleEngine(IFactory factory)
{
factory = _factory;
}
public void Run(string request)
{
var clientname = ParseStringToGetClientName(request)
var clientSettings = ServiceLocator.Current.GetInstance<IClientSettings>(clientname);
var service = _factory.GetService(clientname);
service.DoWork(clientSettings);
}
}
Основные приложения регистрирующие параметры клиента
var container = new UnityContainer();
var clientASettings = ClientSettings.Load("ClientA");
var clientBASettings = ClientSettings.Load("ClientB");
var clientCSettings = ClientSettings.Load("ClientC");
// register singleton instance
container.RegisterInstance("ClientA", clientASettings);
container.RegisterInstance("ClientB", clientBSettings);
container.RegisterInstance("ClientC", clientCSettings);
Вопрос
RuleEngine класс использует Microsoft.Practices.ServiceLocation.ServiceLocator
, чтобы найти ClientSettings
на основе key
. Это означает, что библиотека C#, где реализован механизм правил, должна использовать тот же IOC, что и приложение. (Что в этом случае является Unity)
Как мне сделать библиотеку не осведомленной о контейнере IOC?
Как мне проинсталлировать настройки клиентов здесь, не используя ServiceLocator, когда значение key
известно во время выполнения? Является ли заводская модель единственным способом достижения этого? (Например, так, как я местонахождение службы _factory.GetService(clientname)
)
Взгляните на концепцию [Корень композиции] (http://blog.ploeh.dk/2011/07/28/CompositionRoot/), и в случае, если вы пишете библиотеку многократного использования, прочитайте [эту статью] (http://blog.ploeh.dk/2014/05/19/di-friendly-library/). – Steven
@Steven Спасибо. Я посмотрел на Корзину композиции, короче говоря, ее местоположение в вашем приложении, где вы регистрируете типы с контейнером. Это единственное место, где мы должны использовать контейнер. и это именно то, что я делаю. Мое приложение - это приложение MVC, поэтому все типы будут регистрироваться в global.ascx с контейнером, как было предложено. Однако это не проблема, которую я опубликовал ... (Я также прошел через другую ссылку) – LP13
Чтобы ответить на часть вашего вопроса: нет, фабрики - это не единственный способ и лучший способ достичь этого. Смотрите это: https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=100 – Steven