Static generic builder - c#

I'm trying to implement Asp Net Core-like static builder for my class. Here's what I'm talking about. In Asp Net Core application in Startup method BuildWebHost class WebHost creates IWebHostBuilder:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
I'm interested in UseStartup<Startup>() method, so I want to know about how does this method 'understands' what Startup class it must use?
The signature for this method is:
public static IWebHostBuilder UseStartup<TStartup>(this IWebHostBuilder hostBuilder)
where TStartup : class;
In my application I want to use the similar approach, for example here I have a simple empty interface ICleaner, which is implemented by some Cleaner classes, and then I have CleanerBuilder class, which is responsible for adding appropriate Cleaner classes to a List, configuring them and runs them all after the Build method. Here's my CleanerBuilder class. Here's my CleanerBuilder class:
public class CleanerBuilder
{
private List<ICleaner> _activeCleaners { get; set; }
private CleanerBuilder() { }
public static CleanerBuilder CreateDefaultBuilder(string[] args)
{
var cleanerBuilder = new CleanerBuilder();
/*
* ...
*/
return cleanerBuilder;
}
public CleanerBuilder UseCleaner<ICleaner>()
{
_activeCleaners.Add(???);
return this;
}
public void Build()
{
foreach(var cleaner in _activeCleaners)
{
cleaner.Run();
}
}
}
And the usage is:
CleanerBuilder.CreateDefaultBuilder(args)
.UseCleaner<TempCleaner>()
.Build();
Right now I don't know what to do in UseCleaner method.

The simplest implementation would probably be this:
public CleanerBuilder UseCleaner<TCleaner>() where TCleaner : ICleaner, class, new
{
_activeCleaners.Add(new TCleaner());
return this;
}
However, there is really nothing you gain here over:
public CleanerBuilder UseCleaner(ICleaner cleaner)
{
_activeCleaners.Add(cleaner);
return this;
}
The generic version is more restricted in this simple version, because it has to have an empty constructor. Not cool, maybe it hasn't. What Microsoft does with it's StartUp is to connect it to it's dependency injection container and try to construct it from there. That solves the problem of constructor parameters.
If you have Visual Studio configured to download sources, just press F12 on the UseStartup method to see what they do in there. Alternatively, you can look it up in the source.

The WebHostBuilder class use reflection to create an instance of the startup class. If you want to do something similar then your List implementation needs to store a Type
private List<Type> _activeCleaners { get; set; }
Then in your Add method you could use:
public CleanerBuilder UseCleaner<TCleaner>() where TCleaner : ICleaner, class, new
{
_activeCleaners.Add(typeof(TCleaner));
return this;
}
But in this scenario you would have to research how to create the ICleaner instance when you require it. I think, in this case, nvoigt's answer might be better for you.

What you're trying to achieve is the builder pattern. The job of a builder is to gather dependencies, requirements and parameters for building a type.
The UseCleaner wouldn't normally, or necessarily do much except just store the type of ICleaner in a list for instantiation later on, likely as a result of the user calling the Build method. The simplest here is to require that ICleaner 's have a parameterless constructor.
private readonly List<Type> _activeCleaners;
public CleanerBuilder UseCleaner<ICleaner>()
where ICleaner : class, new()
// We now require that ICleaners has a parameterless constructor
{
_activeCleaners.Add(typeof(ICleaner));
return this;
}
public Cleaner Build()
{
// Lazily create instances of the cleaners
var cleaners = _activeCleaners.Select(Activator.CreateInstance);
// Pass enumerator for instantiated cleaners to the object
return new Cleaner(cleaners);
}
You can use Activator.CreateInstance with parameters as well, or you could use a dependency injection container if you don't want to require a parameterless constructor.

Related

Dependency Injection circular dependency when using a Provider for interface implementations

I'm currently facing an issue for which I have found some partial solutions, but not the one that actually makes me believe I cannot do better.
So, to put in simple, I'm using the Dependency Injection, and I'm facing a circular reference error. Here's something similar to the code I am using.
First, I have a IMyBuilder interface:
public interface IMyBuilder { }
Then, I have an abstract class that implements the interface, and a bunch of class extending the abstract one:
public abstract class MyBuilderBase<DTO> : IMyBuilder
{
public abstract Dto GetDto();
}
public class UserBuilderDto : MyBuilderDto<UserDTO> { ... }
public class ProfessorBuilderDto : MyBuilderDto<ProfessorDTO> { ... }
public class AnimalBuilderDto : MyBuilderDto<AnimalDTO> { ... }
Then, I have a ProviderService, which helps me get the right IMyBuilder based on the DTO type. This ProviderServicedepends on ALL the IMyBuilder, like so:
public class ProviderService
{
private readonly IEnumerable<IMyBuilder> _builders;
public ProviderService(IEnumerable<IMyBuilder> builders)
{
_builders = builder;
}
public IMyBuilder GetBuilder<DTO>()
{
return _builders.OfType<MyBuilderBase<DTO>>().FirstOrDefault();
}
}
Finally, last piece of my code is the registration of the services, like so:
services.AddScoped<IMyBuilder, UserBuilderDto>();
services.AddScoped<IMyBuilder, ProfessorBuilderDto>();
services.AddScoped<IMyBuilder, AnimalBuilderDto>();
services.AddScoped<ProviderService>();
Notice that I register my builder as IMyBuilder: this way I can use the parameter IEnumerable<IMyBuilder> in the constructor of ProviderService.
Ok, now that we have all the inputs, here's the problem: inside the abstract method MyBuilderBase.GetDto I might need some other builder! Therefore, MyBuilderBase needs ProviderService, something like this:
public class AnimalBuilderDto : MyBuilderDto<AnimalDTO>
{
private readonly ProviderService _providerService;
public AnimalBuilderDto(ProviderService providerService)
=> (_providerService) = (providerService)
public AnimalDto GetDto()
{
// using _providerService
}
}
At this point you can clearly see where is my problem:
ProviderService requires AnimalBuilderDto
AnimalBuilderDto requires ProviderService
ProviderService requires AnimalBuilderDto
...
Circular dependency, thus my application crashes.
So, I've investigated this for a while, and I've come up with these solutions.
LAZY INITIALIZATION IN PROVIDER SERVICE
This would be something like here: https://thomaslevesque.com/2020/03/18/lazily-resolving-services-to-fix-circular-dependencies-in-net-core/
Basically, in the constructor of ProviderService I would not directly need to initialize the single IBuilderDto, avoiding the circular dependency..
What I don't like is that it seems a workaround, and not a solution. Also, if by any chance I put a breakpoint into providerService constructor, and inspect the lazy property, the application crashes.. Yeah, workaround.
METHOD INJECTION
I would need to change the signature of the abstract method as follow:
public abstract Dto GetDto(ProviderService providerService);
This way, I would not need the AnimalBuilderDto to depends on ProviderService, REMOVING the circular dependency.
This solution seems a real solution (it removes the circular dependency), but it adds a cost, which is the need of bringing this instance of ProviderService along all the application in order to use it when calling GetDto.
Here's end my investigation. Though, both solution does not seems to fix my problem! Ok, the second one does actually fix the problem, but create another one, which is the need of bringing the instance across all method calls.
Question is: is there any better solution to make a provider class like my ProviderService being reusable inside the same classes that it exploses?
Here's a quick and dirty way to break the circular reference, using an open generic service locator factory.
public interface IMyBuilder<TDTO>
{
TDTO GetDto();
}
public class BuilderFactory<TDTO>
{
private readonly IServiceProvider services;
public BuilderFactory(IServiceProvider services)
{
this.services = services;
}
public IMyBuilder<TDTO> GetBuilder() => services.GetRequiredService<IMyBuilder<TDTO>>();
}
public abstract class MyBuilderBase<DTO> : IMyBuilder<DTO>
{
public abstract DTO GetDto();
}
public class UserDTO { }
public class UserBuilderDto : MyBuilderBase<UserDTO>
{
private BuilderFactory<AnimalDTO> animalFactory;
public UserBuilderDto(BuilderFactory<AnimalDTO> animalFactory)
{
this.animalFactory = animalFactory;
}
public override UserDTO GetDto()
{
var animalBuilder = animalFactory.GetBuilder();
throw new NotImplementedException();
}
}
public class AnimalDTO { }
public class AnimalBuilderDto : MyBuilderBase<AnimalDTO>
{
private BuilderFactory<UserDTO> userFactory;
public AnimalBuilderDto(BuilderFactory<UserDTO> userFactory)
{
this.userFactory = userFactory;
}
public override AnimalDTO GetDto()
{
var userBuilder = userFactory.GetBuilder();
throw new NotImplementedException();
}
}
services.AddScoped(typeof(BuilderFactory<>));
services.AddScoped<IMyBuilder<AnimalDTO>, AnimalBuilderDto>();
services.AddScoped<IMyBuilder<UserDTO>, UserBuilderDto>();
Create an event in consumer class and fire it , once fired make the server class return its current instance
If the Builders use functions from ProviderService that use the Builders too, creating a factory is a way to break the cycle (at least in terms of timing, because the instances of the Builders are created at a later point in time and not upon registration.
However, if the Builders use only functions from ProviderService that do not rely on the Builders themselves, one other option is to move the functionality that is used in GetDto into another class that can be injected into both the Builders and the ProviderService. This way, the circular dependency is removed and both classes still have access to the functionality.
Basically, from
ProviderService -> Builders -> ProviderService
to
ProviderService -> Builders -> SharedFunctions
-> SharedFunctions
Whether or not the Builders and the ProviderService use the same instance of SharedFunctions then depends on the scope that you register it in the IoC container.

How to pass parameter to a class whose dependencies are wired through IoC container?

I have a class that works with a network via multiple resources. Its constructor receives arguments that are resolved at runtime by IoC container (StructureMap):
public NetworkWorker(IRetryService retryService, ILog log)
{ ... }
What I need is to control the number of resources this class uses on a use-case level - for example, client A need NetworkWorker instance that allows only one operation at a time, while client B need 10 ops at a time.
Currently this number is hardcoded in the constructor. The only way I see is to add a method void Configure(int resourceCount) that each client of NetworkWorker would call with a different value. Or may be there's a better way I don't see?
This class can do different things, but number of resources is required for every method call (Get/Send/etc methods).
P.S. is this a known technique (with a Configure method)? If it is, what's the name for it? smth like 'two-step initialization'?
I'll presume this NetworkWorker has multiple methods (otherwise you could just add a parameter to that single method).
You could use a factory pattern:
public interface INetworkWorkerFactory
{
NetworkWorker Create(int numberOfResources);
}
public class NetworkWorkerFactory : INetworkWorkerFactory
{
private readonly IContainer _container;
public NetworkWorkerFactory(IContainer container)
{
_container = container;
}
public NewtorkWorker Create(int numberOfResources)
{
var retryService = _container.GetInstance<IRetryService>();
var log = _container.GetInstance<ILog>();
return new NewtorkWorker(retryService, log, numberOfResources);
}
}
(or simply inject the required dependencies instead of the container)
and then simply
private readonly INetworkWorkerFactory _networkWorkerFactory;
public C(INetworkWorkerFactory networkWorkerFactory)
{
_networkWorkerFactory = networkWorkerFactory;
}
public void M()
{
var networkWorker = _networkWorkerFactory.Create(10);
}
Autofac uses delegate factories for this.
Other containers have equivalent mechanisms of providing auto-generated Abstract Factories - #ploeh has an awesome SO post aggregating examples.
The code in your question would look like so:
public delegate NetworkWorker Factory(IRetryService retryService);
public NetworkWorker(IRetryService retryService, ILog log)
{ ... }
A consumer would look like so (stolen from Alex's answer)
readonly NetworkWorker.Factory _networkWorkerFactory;
public C(NetworkWorker.Factory networkWorkerFactory)
{
_networkWorkerFactory = networkWorkerFactory;
}
public void M()
{
var networkWorker = _networkWorkerFactory(10);
...
}
The key difference is that you do not declare either an interface or an impl for the Abstract Factory - the delegate is the interface and Autofac 'just knows' to make the rest happen.
Another benefit of this approach (other than the code reduction) is that there's a natural path to transitioning the code to Pure DI)

Using Dependency Injection (Autofac) and avoiding Service Locator pattern

I'm taking a stab at properly implementing DI in my Xamarin Android application using Autofac but I'm having issues understanding how I should handle instantiating objects that require data passed into their constructor. For example one of our viewmodels needs a string and a guid passed in to its constructor. Something that looks promising is Delegate Functions offered by Autofac. This is where the line between Service Locator and DI appears to blur, at least in my mind. In order to use the Delegate Functions you must call container.Resolve, or rather it's recommended to use the IComponentContext.Resolve. Many blogs recommend not using Resolve outside of the bootstapper/main entry point. Is there something I am missing here? Is there a better way to create objects using DI? I am familiar with the Factory pattern to create objects but I feel that I'm losing the benefits of DI going that route since I am back to manually passing in services/objects to the newly created object. Thanks for any feedback!
It is not recommended to call container.Resolve() to use a delegate factory. The correct way is shown on the delegate factories page that you already linked to:
public class Portfolio
{
Shareholding.Factory ShareholdingFactory { get; set; }
IList<Shareholding> _holdings = new List<Shareholding>();
public Portfolio(Shareholding.Factory shareholdingFactory)
{
ShareholdingFactory = shareholdingFactory;
}
public void Add(string symbol, uint holding)
{
_holdings.Add(ShareholdingFactory(symbol, holding));
}
}
When the docs show an explicit call to container.Resolve() you should realize that they are not showing best practice, they are simply proving that it can be resolved without coding up a whole new class (like Portfolio) to consume it.
In order to use the Delegate Functions you must call container.Resolve
No, at least not in this case.
Assuming you have registered Shareholding. Now you can ask a dependency on Func<Shareholding>, ie. something hat returns a Shareholding when you call it.
But as the Shareholding constructor has two parameters, it cannot be resolved without supplying those parameters. Just add them to the declaration like this: Func<string, uint, Shareholding>. Now you can resolve the dependency when you supply those parameters.
Here is a better example.
I recently (yesterday) faced the same problem I wound up using the ServiceClient object you see in the code below. This object addresses your question about using the container outside of the bootstrapper. I have read arguments that say not to pass the container around and I think they are mostly valid. In my case however the ServiceClient class represents a single point of entry into my service layer so I thought it was appropriate to pass the container.
The way I use this at the moment is to pass an instance of ServiceClient into my BaseController:
// In Global.asax.cs
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<ServiceClient>().As<IServiceClient>();
BaseController:
public abstract class BaseController<T> : Controller where T :class
{
public IServiceClient ServiceClient { get; set; }
public BaseController(IServiceClient serviceClient)
{
ServiceClient = serviceClient;
}
}
In my controller I can resolve, instantiate, and call a service that uses unmanaged resources with just one line like this:
myViewModel = await ServiceClient.OfType<ICustomerService>().TryAsync(x => x.GetCustomerByID(id));
ServiceClient:
public class ServiceClient : IServiceClient
{
private IComponentContext _container;
public ServiceClient(IComponentContext container)
{
_container = container;
}
public ServiceCallWrapper<T> OfType<T>() where T : class, IDisposable
{
return new ServiceCallWrapper<T>(_container);
}
}
public class ServiceCallWrapper<T> : IServiceCallWrapper<T> where T : class, IDisposable
{
private IComponentContext _container;
internal ServiceCallWrapper(IComponentContext container)
{
_container = container;
}
public void Try(Action<T> method)
{
// consider try/catch/log/throw here
using (T client = _container.Resolve<T>())
{
method(client);
}
}
public TResult Try<TResult>(Func<T, TResult> method)
{
using (T client = _container.Resolve<T>())
{
return method(client);
}
}
public async Task TryAsync(Func<T, Task> method)
{
using (T client = _container.Resolve<T>())
{
await method(client);
}
}
public async Task<TResult> TryAsync<TResult>(Func<T, Task<TResult>> method)
{
using (T client = _container.Resolve<T>())
{
return await method(client);
}
}
}

Ninject interception proxying class with non empty constructor via castle dynamic proxy

I am basing most of my current implementation off the information provided here:
Ninject Intercept any method with certain attribute?
I use a custom planning strategy class which looks for all methods with given attributes (not ninject interceptor attributes) which will then get proxied if it matches the criteria.
An example of usage would be:
Kernel.Components.Add<IPlanningStrategy, CustomPlanningStrategy<LoggingAttribute, LoggerInterceptor>>();
This would then look for any methods which have a [Logging] attribute and will then use the logging interceptor.
However I am currently getting InvalidProxyConstructorArgumentsException from dynamic proxy when it is trying to proxy the methods with related attributes on. Now I remember reading that you need virtual methods, however I do not remember seeing that you HAD to have a parameterless constructor.
All bindings are done against interfaces, and the AOP interceptors happen via attributes and the custom proxy planning class mentioned in the link above.
So is there a way to get dynamic proxy (or the linfu version) to proxy the classes which have constructors with dependencies? (All dependencies are in the Kernel so its not like they cannot be resolved).
Looking at the proxy generating code:
https://github.com/ninject/ninject.extensions.interception/blob/master/src/Ninject.Extensions.Interception.DynamicProxy/DynamicProxyProxyFactory.cs
if (targetType.IsInterface)
{
reference.Instance = this.generator.CreateInterfaceProxyWithoutTarget(targetType, additionalInterfaces, InterfaceProxyOptions, wrapper);
}
else
{
object[] parameters = context.Parameters.OfType<ConstructorArgument>()
.Select(parameter => parameter.GetValue(context, null))
.ToArray();
reference.Instance = this.generator.CreateClassProxy(targetType, additionalInterfaces, ProxyOptions, parameters, wrapper);
}
one can see that ninject's dynamic proxy extension is only passing ConstructorArguments to the Castle Dynamic Proxy Generator.
So - without changes to the ninject extension or creating your own - you need to pass all dependencies as constructor arguments. You could also try out whether property / method injection works (see https://github.com/ninject/ninject/wiki/Injection-Patterns).
If you control the code you could add interfaces to the proxied classes and then use an "interface proxy with target". This allows to decouple proxy instantiation from target (proxied class) instantiation --> target can have dependencies ctor injected without any changes to ninject (-extensions).
Clarification:
Having the following class which should be proxied:
public interface IBar { }
public class Foo
{
public Foo(IBar bar)
{
}
}
And the following binding:
Bind<Foo>().ToSelf().Intercept().With<SomeInterceptor>();
Bind<IBar>().To<Bar>();
And then retrieving a Foo from the ninject container:
IResolutionRoot.Get<Foo>();
won't work.
Putting all constructor arguments on the ninject context to make it work
However, we can change the retrieving of Foo to make it work:
var bar = IResolutionRoot.Get<IBar>();
IResolutionRoot.Get<Foo>(new ConstructorArgument("bar", bar);
Now this is suboptimal because ninject is not doing dependency resolution automatically.
Adding interface to proxied class to make it work better
We can work around the issue by using a "interface proxy with target".
First, we add an interface to the proxied class:
public interface IFoo{ }
public class Foo : IFoo
{
public Foo(IBar bar)
{
}
}
And then we change the binding to:
Bind<IFoo>().To<Foo>().Intercept().With<SomeInterceptor>();
And then retrieving a Foo from the ninject container:
IResolutionRoot.Get<Foo>();
works.
Another, possibly easier (&uglier?) solution
According to #Daniel this works:
Add two constructor to the proxied type:
one protected constructor without parameters. This one is for DynamicProxy to create the proxy.
one public/internal constructor with the arguments, to be used by ninject to instantiate the proxied type.
Ninject will automatically pick the constructor with the most arguments it can resolve.
An alternate approach would be to use a convention based binding for all classes with a method with a [Logging] attribute. However, this means that adding a [Logging] attribute to a method will influence the binding of the object, which may be undesired.
So this is how it would work (verified to work):
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class LoggingAttribute : Attribute
{
}
public interface IClassNotToBeIntercepted
{
void DoSomething();
}
public class ClassNotToBeIntercepted : IClassNotToBeIntercepted
{
public void DoSomething() { }
}
public interface IClassToBeIntercepted
{
void DoNotLogThis();
void LogThis();
void LogThisAsWell();
}
public class ClassToBeIntercepted : IClassToBeIntercepted
{
public void DoNotLogThis() { }
[Logging]
public void LogThis() { }
[Logging]
public void LogThisAsWell() { }
}
public class LoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("interceptor before {0}", BuildLogName(invocation));
invocation.Proceed();
Console.WriteLine("interceptor after {0}", BuildLogName(invocation));
}
private static string BuildLogName(IInvocation invocation)
{
return string.Format(
"{0}.{1}",
invocation.Request.Target.GetType().Name,
invocation.Request.Method.Name);
}
}
public class DemoModule : NinjectModule
{
public override void Load()
{
this.Bind(convention => convention
.FromThisAssembly()
.SelectAllClasses()
.Where(ContainsMethodWithLoggingAttribute)
.BindDefaultInterface()
.Configure(x => x
.Intercept()
.With<LoggingInterceptor>()));
this.Bind<IClassNotToBeIntercepted>()
.To<ClassNotToBeIntercepted>();
}
private static bool ContainsMethodWithLoggingAttribute(Type type)
{
return type
.GetMethods()
.Any(method => method.HasAttribute<LoggingAttribute>());
}
}
And a test:
[Fact]
public void InterceptorTest()
{
var kernel = new StandardKernel();
kernel.Load<DemoModule>();
kernel.Get<IClassNotToBeIntercepted>()
.DoSomething();
kernel.Get<IClassToBeIntercepted>()
.LogThis();
}
Results in the following console output:
interceptor before ClassToBeIntercepted.LogThis
interceptor after ClassToBeIntercepted.LogThis

Ways to setup a Ninject singleton

I have a class (MyFacade) that I injected parameter(s) with Ninject:
class MyFacade
{
IDemoInterface demo;
public MyFacade(IDemoInterface demo)
{
this.demo = demo;
}
public void MyMethod()
{
Console.WriteLine(demo.GetInfo());
}
}
Of course, I have to setup the Ninject to inject the appropiate implementation of my parameter (IDemoInterface)
I know, I can instantiate MyFacade object by doing kernel.Get<MyFacade>(); without setting anything else. Currently my facade doesn't have an interface (because it is my only implementation, maybe I will add its interface for standard proposes)
if I want to make this facade singlenton, I know two ways: create a empty constructor and pass a parameter by doing this kernel.Get<IDemoInterface>(); or by setup Ninject like: kernel.Bind<MyFacade>().To<MyFacade>().InSingletonScope();
The second one look a better approach, but do you know any other way to setup it in a singleton way?
When setting up your bindings, you need to bind your dependencies. It is always better to setup your dependencies in your bindings, as opposed to doing a kernel.Get<T>() in a constructor. You are using IOC, so leverage the framework you are using to do the injection for you.
In your second example binding, what you are missing is binding in your IDemoInterface. Your bindings should look like this:
//bind the dependency to the implementation.
kernel.Bind<IDemoInterface>().To<DemoInterface>();
//since you bound your dependency, ninject should now have
// all the dependencies required to instantiate your `MyFacade` object.
kernel.Bind<MyFacade>().To<MyFacade>().InSingletonScope();
If you do not want the container to manage the lifecycle of your singleton by using InSingletonScope(), but still wants it to get injected, I can think of 2 ways to go about it. Choose which one suits better to your needs. Consider the following ISingleton (name your interface) implementation:
public class ConcreteSingleton : ISingleton
{
private static readonly Lazy<ConcreteSingleton> _instance = new Lazy<ConcreteSingleton>(() => new ConcreteSingleton());
private ConcreteSingleton() { }
public static ConcreteSingleton Instance
{
get
{
return _instance.Value;
}
}
}
Alter the singleton class to have a GetInstance(...) method
In this method (my preferred approach), you won't be calling kernel.Inject(instance) each time, only for the first time the singleton is initialized. Adding the following method to your ConcreteSingleton class:
public static ConcreteSingleton GetInstance(IKernel kernelForInjection)
{
if (_instance.IsValueCreated == false)
{
kernelForInjection.Inject(_instance.Value);
}
return _instance.Value;
}
And using this binding:
kernel.Bind<ISingleton>().ToMethod(c => ConcreteSingleton.GetInstance(c.Kernel));
Will achieve the desired behavior of not having a public constructor but enabling your facade to be efficiently injected.
Perform injection each time the ISingleton instance is requested
If by any reason you are not allowed to modify your ConcreteSingleton: This approach will wrap the singleton creation in a provider to efficiently inject the instance only for the first time it is created. It is important to note that the provider itself must be registered as a singleton.
internal class ConcreteSingletonProvider : Provider<ISingleton>
{
public IKernel Kernel { get; set; }
//Just a wrapper
private readonly Lazy<ISingleton> _lazy = new Lazy<ISingleton>(() => ConcreteSingleton.Instance);
public ConcreteSingletonProvider(IKernel kernel)
{
Kernel = kernel;
}
protected override ISingleton CreateInstance(IContext context)
{
if (_lazy.IsValueCreated == false)
{
Kernel.Inject(ConcreteSingleton.Instance);
}
return _lazy.Value;
}
}
And your bindings should be like this:
kernel.Bind<ISingleton>().ToProvider<ConcreteSingletonProvider>();
kernel.Bind<ConcreteSingletonProvider>().ToSelf().InSingletonScope();
This gist has a complete working sample for the above approach.
Hope that helps!

Categories

Resources