-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
From @tuespetre on Friday, December 18, 2015 8:00:37 AM
User Story / Use Case Scenario
As a developer, I want to extend a previously registered service by wrapping it with another service that exposes the same interface.
See: aspnet/Mvc#3739
Example interface and implementations
public interface IMyService
{
void DoSomething();
}
public partial class DefaultMyService
{
public partial void DoSomething();
}
public partial class DecoratorForMyService
{
private IMyService decorated;
public DecoratorForMyService(IMyService decorated)
{
this.decorated = decorated;
}
public partial void DoSomething();
}
Examples of ways to set up the service collection
Using constructor resolution
var collection = new ServiceCollection();
collection.AddTransient<IMyService, DefaultMyService>();
collection.AddTransient<IMyService, DecoratorForMyService>();
var provider = collection.BuildServiceProvider();
var service = collection.GetService<IMyService>(); // Returns the constructed DecoratorForMyService
Using implementation factories
var collection = new ServiceCollection();
collection.AddTransient<IMyService, DefaultMyService>();
collection.AddTransient<IMyService>(_provider =>
{
// Returns the previously registered IMyService.
// Calling _provider.GetService<IEnumerable<IMyService>>() here
// would return a collection containing all registered IMyServices
// except for this one.
var decorated = _provider.GetService<IMyService>();
return new DecoratorForMyService(decorated);
});
var provider = collection.BuildServiceProvider();
var service = collection.GetService<IMyService>(); // Returns the constructed DecoratorForMyService
Behavioral Considerations
Currently, the above two approaches result in 'Circular Dependency' exception and a StackOverflowException
, respectively. An implementation that allowed for the above scenarios would effectively prevent the StackOverflowException
entirely, and throw the 'Circular Dependency' exception only when there are no other previously registered services for the type that is being resolved result in circular dependency scenarios throwing the "Unable to resolve service..." kind of exception, which should in itself sufficiently convey the circularity for those cases.
Copied from original issue: aspnet/DependencyInjection#340