Столкнулся с тем, что не могу понять как реализовать в программе один момент с передачей параметров через DI.
Пытаюсь реализовать подобие паттерна фабрики, и если мой пример максимально упростить, то интерфейсы выглядят так.
public interface ISession
{
bool Login();
object Execute(string command);
}
public interface ISessionFactory
{
ISession Create(string name)
}
И их реализация. Набирал прямо тут, мог ошибиться.. прошу понять и простить.
public class Session : ISession
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<Session> _logger;
private HttpClient _httpClient;
private string _clientname;
private string _clientname;
private string _password;
public Session(ILogger<Session> logger, IHttpClientFactory httpClientFactory)
{
_logger = logger;
_httpClientFactory = httpClientFactory;
}
public Init(string clientname, string username, string password)
{
_clientname=clientname;
_clientname=username;
_password=password;
}
bool Login()
{
_httpClient = _httpClientFactory.CreateClient(_clientname);
var response = await _httpClient.PostAsync($"login?usr={_username}&pwd={_password}", null);
// do etc
}
public object Execute(string command)
{
// do
}
}
public class SessionFactory : ISessionFactory
{
public SessionFactory(ILogger<Fabric> logger, IOptions<MyOptions> myOptions, IFabric<ISession> sessionFabric)
{
_logger = logger;
_myOptions = myOptions.Value;
_sessionFabric = sessionFabric;
}
ISession Create(string name)
{
var session = _sessionFabric.Create();
session.Init(name, _myOptions[name].Username, _myOptions[name].Password);
session.Login();
return session;
}
}
public class Factory<T> : IFactory<T>
{
private readonly Func<T> _initFunc;
public Factory(Func<T> initFunc)
{
_initFunc = initFunc;
}
public T Create()
{
return _initFunc();
}
}
public interface IFactory<T>
{
T Create();
}
***
public static void AddFactory<TService, TImplementation>(this IServiceCollection services)
where TService : class
where TImplementation : class, TService
{
services.AddTransient<TService, TImplementation>();
services.AddSingleton<Func<TService>>(x => () => x.GetService<TService>());
services.AddSingleton<IFactory<TService>, Factory<TService>>();
}
Во первых у меня получается какая-то фабрика в фабрике. Первая фабрика создает обьект сессии, вторая настраивает. Чутье подсказывает мне, что так быть не должно.
Во-вторых, я не могу понять, как мне передать параметры clientname, username, password через DI так, чтобы их нельзя было сменить во время сессии и нарваться на исключение от httpClient. Защита от дурака. Ну кроме очевидных решений вроде хранения булевой переменной вроде alreadyInit.