Here is a class which will be instantiated only once through out the lifetime of the application
public class SampleClass //instantiated only once
{
public void DoOpertation()//will be called by every incoming request
{
var dependentService = new SampleService();
//do operation on dependentService instance
....
}
}
Method "DoOpertation" operation will be called many time during the application lifetime.
In "DoOpertation" method I'm instantiating 'SampleService' using 'new' keyword which I don't want to do for the below reasons
- It breaks single responsibility principle (SRP) as creating SampleService class instance is not SampleClass's responsibility
- Create tight coupling between SampleClass & SampleService classes which makes unit testing harder atleast
I can't use DI container for constructor injection of dependencies as SampleClass get instantiated only once in the application lifetime but where as every invocation of DoOpertation method (which lives inside SampleClass) requires new instance of SampleService class to work properly.
How to inject SampleService class new instance on every invocation of DoOpertation() without using 'new' keyword?
Modification as per Athanasios Kataras's suggestion
Introduced new factory class
public class LoggerFactory : ILoggerFactory
{
public IEventLog CreateLogger(string type)
{
if (type == "Event")
return new EventLog();
else
return null;
}
}
public interface ILoggerFactory
{
IEventLog CreateLogger(string type);
}
On the class which instantiate only once,
public class SampleClass //instantiated only once
{
public void DoOpertation()//will be called by every incoming request
{
var eventLogBuilder = _factory.CreateLogger("Event");
//var dependentService = new SampleService(); //replace with above simple factory class call
//do operation on dependentService instance
....
}
}
CodePudding user response:
I would go with a simple factory solution.
- Create the
IServiceFactoryinterface with theCreateService(options)function - Create a class implementing it with the responsibility of returning the proper service insurance.
- Inject the factory implementation
In your function call the factory interface. This will also enable you to change the creation strategy in the future if you need it.
The solution going with the built in provider, looks like a service locator anti pattern to me, so I would advise against it.
CodePudding user response:
Register Sampleclass as a singleton and SampleService as a transient. Then inject IServiceProvider into SampleClass. Use the ServiceProvider to then create the SampleServer.
services.AddSingleton<SampleClass>();
services.AddTransient<SampleService>();
...
public class SampleClass //instantiated only once
{
private readonly IServiceProvider _provider;
public SampleClass(IServiceProvider provider)
{
_provider = provider;
}
public void DoOpertation()//will be called by every incoming request
{
var dependentService = _provider.GetService<SampleService>();
//do operation on dependentService instance
....
}
}
