For example, I have a class, which does different requests to some external API:
internal class ServiceCore : IDisposable
{
public ServiceCore(IConfiguration configuration, Func<HttpMessageHandler> handler)
{
_configuration = configuration;
_handler = handler;
devKey = _configuration.GetSection("ApiBillCom:DevKey").Value;
client = new HttpClient(_handler())
{
BaseAddress = new Uri(_configuration.GetSection("ApiBillCom:ApiUrl").Value)
};
if (_sessionId == null || !_sessionId.IsValueCreated)
SetSessionId();
}
public async Task<JToken> ListJTokenAsync(int start, int count, string endpoint, bool nested = false, List<FilterData> filterData = null)
{
//....
}
public async Task<List<T>> ListAsync<T>(string endpoint, int start, int count, bool nested = false, List<FilterData> filterData = null)
{
//.....
}
ok, but each call requires sessionId, which we can get calling LoginAsync method before. This LoginAsync method can be as private method inside this ServiceCore class:
private void SetSessionId()
{
_sessionId = null;
LoginCore loginCore = new LoginCore(_configuration, _handler);
_sessionId = new Lazy<string>(() => LoginAsync().Result);
}
private async Task<string> LoginAsync()
{
but then, seems, Single Responsible Principle is violated (because then ServiceCode has 2 duties, get (or put) data to API and supports session. I did refactoring and moved it to special class:
internal class LoginCore
{
private readonly IConfiguration _configuration;
private readonly Func<HttpMessageHandler> _handler;
public LoginCore(IConfiguration configuration, Func<HttpMessageHandler> handler)
{
_configuration = configuration;
_handler = handler;
}
internal async Task<string> LoginAsync(string devKey)
{
// ....
}
}
Right now no SRP violation, every class has only one duty (ServiceCore - work with API, LoginCore - get actual sessionId), but I'm not sure, that I need to do it (separate login workflow to another class). Right now I have to pass one parameter to LoginAsync (with private method I have not to do it, because devKey is private property inside ServiceCore), have to write constructor for LoginCore and pass the same dependency injection parameters, which I passed to ServiceCore. I have to create LoginCore instance before calling LoginAsync
I will not use this LoginCore somewhere else, only in ServiceCore, I need not to have dependency injection (because I need not to replace LoginCore, method LoginAsync is actual for any calls. I see only one benefit: I can mark LoginCore as:
[assembly: InternalsVisibleTo("BillComRealTest")]
and write unit test specially only for LoginAsync method, with mock HttpMessageHandler.
Should I create this separate class with one method for following SRP or enough to create just private method inside ServiceCore ?
Aucun commentaire:
Enregistrer un commentaire