Если ваш пакет содержит класс, который настраивает IServiceCollection
, например:
public class MyPackageInstaller
{
public void Install(IServiceCollection services)
{
// Your package registers its services
}
}
Тогда это также может быть момент, когда вы разрешаете потребителю вносить необязательные изменения. Например, вы можете определить такой класс, который позволяет потребителю указывать реализации для определенных сервисов:
public class MyPackageRegistrationOptions
{
public ServiceDescriptor FooServiceDescriptor { get; private set; }
public void AddFooService(ServiceDescriptor fooDescriptor)
{
if (fooDescriptor.ServiceType != typeof(IFooService))
{
throw new ArgumentException("fooDescriptor must register type IFooService.");
}
FooServiceDescriptor = fooDescriptor;
}
}
Теперь ваш установщик может использовать эти параметры и зарегистрировать либо реализацию, указанную потребителем, либо собственную настройку по умолчанию.
public class MyPackageInstaller
{
private readonly MyPackageRegistrationOptions _options;
public MyPackageInstaller(MyPackageRegistrationOptions options = null)
{
_options = options;
}
public void Install(IServiceCollection services)
{
if (_options?.FooServiceDescriptor != null)
services.Add(_options.FooServiceDescriptor);
else
// here's your default implementation
services.AddSingleton<FooService>();
}
}
Использование:
var services = new ServiceCollection();
var options = new MyPackageRegistrationOptions();
options.AddFooService(ServiceDescriptor.Singleton<IFooService, AlternateFooService>());
var installer = new MyPackageInstaller(options);
installer.Install(services);
На первый взгляд это выглядит как более длинный способ получить тот же результат. Преимущество состоит в том, что он позволяет вам более четко определить, какие услуги следует или не следует переопределять. Таким образом, вы чувствуете, что вы работаете с преднамеренно выставленными вариантами конфигурации, а не как ковыряетесь во внутреннем пакете.
Вместо того, чтобы разрешать потребителю добавлять ServiceDescriptor
, вы можете разрешить ему указывать только тип службы, а ваша конфигурация определяет, как она будет зарегистрирована (singleton, transient и т. Д.)
Это также полезный шаблон, когда библиотека зависит от значений конфигурации, таких как строки подключения, которые должны быть предоставлены потребителем. Вы можете сделать их обязательными аргументами для построения опций, а затем потребовать опций для построения установщика, или просто сделать их обязательными аргументами в установщике. Теперь невозможно установить пакет без необходимых значений конфигурации.