Stack overflow when resolving services with Ninject - c#

I'm trying to resolve a known fixed list of Foo services (in singleton scope) using NInject; this resolution happens in a FooProvider's constructor. The problem is that each Foo will need this provider as well.
public interface IFoo { }
public interface IFooProvider { }
public class Foo : IFoo
{
private readonly IFooProvider _provider;
public Foo(IFooProvider provider)
{
_provider = provider;
}
}
public class FooProvider : IFooProvider
{
private List<IFoo> _allFooServices;
public FooProvider(IKernel kernel)
{
_allFooServices = kernel.GetAll<IFoo>().ToList();
}
}
public class Program
{
private static void Main(string[] args)
{
var IoC = new StandardKernel();
IoC.Bind<IFoo>().To<Foo>().InSingletonScope();
IoC.Bind<IFooProvider>().To<FooProvider>().InSingletonScope();
var foo = IoC.Get<IFoo>();
}
}
There is a logical cyclic loop here, and obviously the stack overflow shows its going down it. However, I have both interface bound to singletons.
Thinking about it; we try to resolve IFoo, which then needs resolution of IFooProvider, itself needing a list of IFoo... but we haven't resolved for any IFoo singletons yet because we're still trying to resolve it!
So how could I work around this?
[Edit] Possible solution; delay buffering of IFoo service instances.
public FooProvider(IKernel kernel)
{
_kernel = kernel;
}
public IFoo Find(object context)
{
if (_allFooServices == null)
_allFooServices = _kernel.GetAll<IFoo>().ToList();
return _allFooServices.Where(...
[Why?]
The general idea is to avoid the service locator pattern, as I've seen it described as an anti-pattern. So, rather than try to resolve services through the dependency injector during run time; you try to get a list of services during setup. The problem with this though, is that if any of your services want to find other services, you have the above problem.

You cannot resolve this cyclic dependency with Ninject. You are not even able to create such object graph by hand.
First you have to remove the cyclic dependency from at least one constructor. You can move this dependency to property and use property injection.
public class Foo : IFoo
{
[Inject]
public IFooProvider Provider { get; set; }
}
If you want to avoid service-locator pattern you should remove dependency on IKernel from the constructor of FooProvider and use the injection of collection of registered IFoo implementations instead.
public class FooProvider : IFooProvider
{
private List<IFoo> _allFooServices;
public FooProvider(IEnumerable<IFoo> fooServices)
{
_allFooServices = fooServices.ToList();
}
}

You could use property injection with one of them.
public interface IFoo
{
}
public interface IFooProvider
{
}
public class Foo : IFoo
{
[Inject]
public IFooProvider Provider { get; set; }
}
public class FooProvider : IFooProvider
{
private List<IFoo> _allFooServices;
public FooProvider(IKernel kernel)
{
_allFooServices = kernel.GetAll<IFoo>().ToList();
}
}
private static void Main(string[] args)
{
var IoC = new StandardKernel();
IoC.Bind<IFoo>().To<Foo>().InSingletonScope();
IoC.Bind<IFooProvider>().To<FooProvider>().InSingletonScope();
var foo = IoC.Get<IFoo>();
}

Really this seems like bad design, but to answer your question directly, don't instantiate _allFooServices in the constructor. You can do something like this:
private List<IFoo> _allFooServices;
private List<IFoo> AllFooServices
{
get { return _allFooServices ?? (_allFooServices = Kernel.GetAll<IFoo>().ToList()) }
}
Perhaps you can choose a more concrete example, rather than Foo.

Related

What is the best way to use an Interface with multiple classes where classes don't implement the same subinterfaces?

I'm trying to create an generic service-interface per logic-class to communicate with the database.
See code examples for an explanation better than words.
For example:
Foo
public interface ICreateFoo
{
void CreateFoo(Foo foo);
}
public interface IReadFoo
{
void ReadFoo(Foo foo);
}
Bar
public interface ICreateBar
{
void CreateBar(Bar bar);
}
public interface IReadBar
{
void ReadBar(Bar bar);
}
IFooService
public interface IFooService : ICreateFoo, IReadFoo, IReadBar
{ }
FooService instance
public class FooService : ICreateFoo, IReadFoo
{
public void CreateFoo(Foo foo){
//Something
}
public void ReadFoo(Foo foo){
//Something
}
}
BarService instance
public class BarService : ICreateBar, IReadBar
{
public void CreateBar(Bar bar){
//Something
}
public void ReadBar(Bar bar){
//Something
}
}
FooLogic instance
public class FooLogic : IFooService
{
private readonly IFooService _fooService;
public FooLogic(IFooService fooService) {
_fooService = fooService;
}
public void CreateFoo(Foo foo){
//Check if bar exists
if(_fooService.ReadBar())
_fooService.AddFoo(foo);
else
//nothing
}
}
But the dependency injection ofcourse doesn't know which service class instance it should get, is this a bad usage of interfaces? Because it looks clean to me, but I don't know how to implement yet.
The reason I came up with this is because I need to know if Bar exists or not before adding Foo to the database. I wanted the classes according to the SOLID-principles (each class has it's own responsibilities). Or is it better to inject each service in the Logic so, like this:
public class FooLogic
{
private readonly IFooService _fooService;
private readonly IBarService _barService;
public FooLogic(IFooService fooService, IBarService barService) {
_fooService = fooService;
_barService = barService;
}
public void CreateFoo(Foo foo){
//Check if bar exists
if(_barService.ReadBar())
_fooService.AddFoo(foo);
else
//nothing
}
}
Maybe you have a complete different but better approach, let me know! I appreciate code examples :)
Keep it simple!
Create FooService that implements IFooService.
FooLogic should be removed. You can implement the logic inside the method CreateFoo.
Since FooService will impement all the methods, you can call ReadBar() instead of _barService.ReadBar(), there is no need for composition since you already have IFooService inheriting from all other interfaces.
This way, we are still respecting the dependency injection pattern.

Improve code with Factory Pattern and DI

I am looking on ways to improve the following code:
public interface IExample{ void Do(); }
public interface IExampleA: IExample {}
public class ExampleA: IExampleA { public void Do(); }
public interface IExampleB: IExample {}
public class ExampleB: IExampleB { public void Do(); }
public interface IExampleFactory{
IExample Make(TypesOfExamples thisIsAnEnum);
}
public class ExampleFactory: IExampleFactory {
IExampleA _exampleA;
IExampleB _exampleB;
public ExampleFactory(IExampleA exampleA, IExampleB exampleB)
{
_exampleA = exampleA;
_exampleB = exampleB;
}
public IExample Make(TypesOfExamples thisIsAnEnum)
{
switch(thisIsAnEnum)
{
case A: return _exampleA;
case B: return _exampleB;
}
}
}
Basically what I don't like is having to use the IExampleA and IExampleB, they are there only for being injected:
container.Bind<IExampleA>().To.<ExampleA>();
container.Bind<IExampleB>().To.<ExampleB>();
container.Bind<IExampleFactory>().To.<ExampleFactory>();
And it would be used like this
public class ExampleUsage()
{
ExampleFactory _exampleFactory;
public ExampleUsage(ExampleFactory exampleFactory)
{
_exampleFactory = exampleFactory;
}
public void useFactory(Test obj)
{
var implementation = _exampleFactory.Make(obj.ThisIsAnEnum);
implementation.Do();
}
}
Any pointers would be appreciated, thanks!
**Edit I had forgotten to mention that both ExampleA and ExampleB has some dependencies that need to be taken care of by the DI
public class ExampleA: IExampleA
{
IDependencyA _dependencyA;
IDependencyB _dependencyB;
public ExampleA(IDependencyA dependencyA, IDependencyB dependencyB)
{
_dependencyA = dependencyA;
_dependencyB = dependencyB;
}
public void Do();
}
public class ExampleB: IExampleB
{
IDependencyA _dependencyA;
IDependencyB _dependencyB;
IDependencyC _dependencyC;
public ExampleA(IDependencyA dependencyA, IDependencyB dependencyB, IDependencyC dependencyC)
{
_dependencyA = dependencyA;
_dependencyB = dependencyB;
_dependencyC = dependencyC;
}
public void Do();
}
container.Bind<IDependencyA>().To.<DependencyA>();
container.Bind<IDependencyB>().To.<DependencyB>();
container.Bind<IDependencyC>().To.<DependencyC>();
I think you are doing wrong with the Factory.
There is no point to inject ExampleA and ExampleB to the Factory.
Since the factory pattern is responsible for creation, therefore you can do instantiation from inside factory class.
This could be easy to replace the factory with the other implementations of the IExampleFactory.
*Edited added more details.
Actually the DI container can be considered as a factory (both are responsible for objects creation).
But if you want to go the factory way, you can implement you own instantiation logic.
Of course, you need to handle the dependencies by the factory.
The factory interface is better to define the objects to be created separately.
public interface IExampleFactory
{
IExampleA CreateExampleA();
IExampleB CreateExampleB();
}
Then the concrete factory should handle the instantiation process of each object.
you can do anything to get all dependencies to instantiate the object (each object can have different dependencies).
public class ExampleFactory: IExampleFactory
{
IExampleA CreateExampleA()
{
//instantiating concrete object A with its dependencies
return concreteA;
}
IExampleB CreateExampleB();
{
//instantiating concrete object B with its dependencies
return concreteB;
}
}

Generic registration in Windsor with UsingFactoryMethod

We currently have code that looks something like below, with a factory being injected in to a lot of classes, which then call the factory to get an instance of what they want.
public class Service
{
public Service(IFactory factory)
{
_car = factory.GetCar<Entity>();
}
}
public class Car : ICar
{
}
public interface IFactory
{
ICar<TEntity> GetCar<TEntity>();
IBoat<TEntity> GetBoat<TEntity>();
}
public class Factory : IFactory
{
ConnectionDetails _connectionDetails;
public Factory(ConnectionDetails connectionDetails)
{
_connectionDetails = connectionDetails;
}
TEntity GetCar<TEntity>()
{
var car = new Car<TEntity>(_connectionDetails);
car.Initialize();
return car;
}
}
I was hoping to be able to create a solution that would allow for request a dependency directly on the Car<TEntity> without needing to go through the factory first.
Below is an example of installing for a single TEntity, but how would I set this up to be generic?
I've tried using open generics, but I can't see how I can get the correct return type out of .UsingFactoryMethod().
I know I can get the RequestedType out of the CreationContext, but I don't see how I can use that to solve this problem.
public class Installer : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<ICar<TEntity>>().UsingFactoryMethod(
kernel =>
{
var factory = kernel.Resolve<IFactory>();
return factory.GetCar<TEntity>();
}));
}
}
Personally I find that factories mixed with dependency injection can be a bit of anti-pattern, since it hides implementation/creation details somewhere other than the object graph root. In addition, when mixing the two it becomes unclear who ultimately has the responsibility for creating and maintaining objects and their lifecycles.
I'd recommend you move to allowing the container to fully handle creation details based on common base interfaces/classes.
void Main()
{
var container = new WindsorContainer();
container.Install(new Installer());
var car = container.Resolve<Car>();
car.Dump();
}
public class Service
{
private ICar<CarEntity> _car;
public Service(ICar<CarEntity> car)
{
_car = car;
}
}
public class TEntity { }
public class CarEntity : TEntity { }
public class BoatEntity : TEntity { }
public interface ICreatable { }
public interface ICar<TEntity> : ICreatable { }
public class Car : ICar<TEntity>
{
private ConnectionDetails _connectionDetails;
public Car(ConnectionDetails connectionDetails)
{
_connectionDetails = connectionDetails;
Initialize();
}
public void Initialize() {}
}
public class ConnectionDetails { }
public class Installer : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<ConnectionDetails>()
.ImplementedBy<ConnectionDetails>());
container.Register(
Classes.FromAssemblyInThisApplication()
.BasedOn(typeof(ICreatable))
.WithServiceAllInterfaces()
.WithServiceSelf()
.LifestyleTransient());
}
}
You can use Castle's Typed Factory Facility to achieve this.
First you need to create an interface that Castle will implement:
public interface IFactory
{
ICar<TEntity> CreateCar<TEntity>(ConnectionDetails connectionDetails);
IBoat<TEntity> CreateBoat<TEntity>(ConnectionDetails connectionDetails);
void Release(object component); // left type as object so it can release either a boat or a car
}
With this implementation as long as your object is registered in the container with the closed generic type as its service name castle will automatically be able to find the correct object.
Then you just need to add the facility and register your factory interface:
kernel.AddFacility<TypedFactoryFacility>();
kernel.Register(Component.For<IFactory>().AsFactory());
The article I linked at the top also covers the naming semantics of the methods in the interface as some words are given special meaning.

Autofac dynamic invocation with Func and Dependency Injection

Providing that I have a class as follows
public class Foo
{
public Foo(string someTitle, IFooService fooService)
{
// do stuff
}
}
I know that I can instantiate it like this using DI and autofac
public class Bar
{
public Bar(Func < string, IFooService, Foo > foo, IFooService fooService)
{
var foo = foo("some string", fooService);
}
}
but I'm wondering if there's any way for Bar to not have to know anything about IFooService? I'd like to not have to inject IFooService into Bar just to satisfy the func.
Essentially something like this
// pseudo code - don't use
public class Bar
{
public Bar(Func < string, Foo > foo)
{
var foo = foo("some string");
}
}
What I'm really trying to do in my app is remove all instances of Service Location, and rely solely on Dependency Injection.
Autofac should be able to do exactly what you want by using the Func<T> implicit relationship.
Here is a small repro showing how you can omit the IFooService parameter in the Func<T> and as long as the other dependencies can be resolved by Autofac, you're good to go.
Sample types that do some crazy work...
public class Bar
{
private Foo _foo;
// This constructor looks like what you're aiming for...
public Bar(Func<string, Foo> factory)
{
this._foo = factory("title");
}
public void ShowMeCoolStuff()
{
this._foo.DoWork();
}
}
public class Foo
{
private string _title;
private IFooService _service;
// The Foo class takes the title AND an IFooService...
public Foo(string title, IFooService service)
{
this._title = title;
this._service = service;
}
public void DoWork()
{
Console.WriteLine("Foo title = {0}", this._title);
this._service.DoMoreWork();
}
}
public interface IFooService
{
void DoMoreWork();
}
public class FooService : IFooService
{
public void DoMoreWork()
{
Console.WriteLine("FooService doing more work.");
}
}
When you register, make sure all the dependencies are registered - Foo, Bar, something implementing IFooService:
var builder = new ContainerBuilder();
builder.RegisterType<Foo>();
builder.RegisterType<Bar>();
builder.RegisterType<FooService>().As<IFooService>();
var container = builder.Build();
When you resolve, everything chains down the line. This resolution...
var bar = container.Resolve<Bar>();
bar.ShowMeCoolStuff();
...will yield the following console output:
Foo title = title
FooService doing more work.
There is fairly robust documentation with examples over on the Autofac site.
That's where you use factories for:
public interface IFooFactory
{
Foo CreateFoo(string value);
}
And bar can simply depend on IFooFactory.
The implementation can look as follows:
public class FooFactory : IFooFactory
{
private readonly IFooService fooService;
public FooFactory(IFooService fooService)
{
this.fooService = fooService;
}
public Foo CreateFoo(string value)
{
return new Foo(value, this.fooService);
}
}
But the given string seems like a runtime value, i.e. a value that changes from request to request or from call to call. Prevent mixing runtime values with design time dependencies as explained here, here and here. Instead, pass the runtime value as method argument to the Foo methods you are calling. That will completely remove the problem.

Ninject Property Injection on base class

I'm attempting to inject a property using ninject. Given the two bindings in the ninject module below, I would expect the ConcreteDependency to be injected into B. However, it seems that WhenInjectedInto doesn't consider the type being injected into, just the declaring type of the target (property in this case).
Is there a way to achieve the behaviour I expected?
static void Main(string[] args)
{
var kernel = new StandardKernel(new TestModule());
var b = kernel.Get<B>();
var c = kernel.Get<C>();
}
class TestModule : NinjectModule
{
public override void Load()
{
Bind<IDependency>().To<EmptyDependency>();
Bind<IDependency>().To<ConcreteDependency>().WhenInjectedInto<B>();
}
}
abstract class A
{
[Inject]
public IDependency Dependency { get; set; }
}
class B : A {}
class C : A {}
interface IDependency {}
class EmptyDependency : IDependency { }
class ConcreteDependency : IDependency { }
You should use constructor injection instead of property injection if possible. This is a better technique, which is recommended by Mark Seeman, because makes dependencies required for object construction explicit and object signature via constructor is more expressive. Code should look like this:
abstract class A
{
public IDependency Dependency { get; private set; }
public A (IDependency dependency)
{
Dependency = dependency;
}
}
class B : A
{
public B (IDependency dependency)
: base(dependency)
{
}
}
class C : A
{
public C (IDependency dependency)
: base(dependency)
{
}
}
interface IDependency { }
class EmptyDependency : IDependency { }
class ConcreteDependency : IDependency { }
Configuration will be the same as in you example. The following test passes
[Test]
public void TestSpecificBindingToObjectB()
{
var kernel = new StandardKernel(new TestModule());
var b = kernel.Get<B>();
var c = kernel.Get<C>();
Assert.AreNotEqual(b.Dependency.GetType(), c.Dependency.GetType());
Assert.AreEqual(typeof(ConcreteDependency), b.Dependency.GetType());
}
If you have an optional dependency with default implementation and you are ok with decorating your classes with Inject attribute, you can can pull parent information from request, like this:
class TestModule : NinjectModule
{
public override void Load()
{
Bind<IDependency>().To<EmptyDependency>();
Bind<IDependency>().To<ConcreteDependency>().When(req =>req.ParentContext.Request.Service == typeof(B));
}
}
Then the same test given above passes for your class hierarchy with property injection.
In order to check against a concrete type, you can use ParentContext.Plan.Type on the IRequest interface. This should give you the behaviour you expected from WhenInjectedInto. For example:
When(req => req.ParentContext.Plan.Type == typeof(B))

Categories

Resources