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