To achieve IoC I used to set up instances using DI as following:
class Foo
{
IBar _bar
public foo(IBar bar)
{
_bar = bar;
}
}
Anything that is newed up is then done by autofac. But how do I (or can I) use autofac to achieve independency when assigning new instances isn't possible at startup?
E.g.
class Foo
{
List<IBar> _barList;
public foo(List<IBar> barList)
{
_barList = barList;
}
FooFunction()
{
_barList.Add(new Bar(new qux));
}
}
public class Baz : IBaz
{
Iqux _qux;
Baz(Iqux qux)
{
_qux = qux;
}
}
Here I added "qux" as well to show what I likely want to achieve. No problem if everything is set up at startup. But because I don't now the numbers of "buz" items the list is going to have at startup I have to add "buz" items during runtime (that requires "qux").
Well, the very goal is to get testable modules. Therefore I don't want to mention the class but only its interface, which is not possible if I have to new up something (or am I wrong?).
Related
In my project I use composite pattern and I want to register and resolve this hierarchy using StructureMap.
The code looks like this
interface IFoo
{
void Do();
}
class Foo1 : IFoo
{
public void Do()
{
Console.WriteLine("Foo1");
}
}
class Foo2 : IFoo
{
public void Do()
{
Console.WriteLine("Foo2");
}
}
class CompositeFoo : IFoo
{
private readonly IEnumerable<IFoo> foos;
public CompositeFoo(IEnumerable<IFoo> foos)
{
this.foos = foos;
}
public void Do()
{
foreach (var foo in this.foos)
{
foo.Do();
}
}
}
class Bootstrapper
{
public static void Run()
{
var container = new Container(c =>
{
c.For<IFoo>().Add<Foo1>();
c.For<IFoo>().Add<Foo2>();
c.For<IFoo>().Use<CompositeFoo>();
});
// throws exception
var result = container.GetInstance<IFoo>();
result.Do();
}
}
The specified code throws this exception
Bi-directional dependency relationship detected!
Check the StructureMap stacktrace below:
1.) Instance of IFoo (CompositeFoo)
2.) All registered children for IEnumerable<IFoo>
3.) Instance of IEnumerable<IFoo>
4.) new CompositeFoo(*Default of IEnumerable<IFoo>*)
5.) CompositeFoo
6.) Instance of IFoo (CompositeFoo)
7.) Container.GetInstance<IFoo>()
I can not find anything related to this in the official documentation or anywhere on the internet. Is this at all possible without manually specifying all possible dependencies?
The way i see it you have a couple of options:
Register CompositeFoo as CompositeFoo and not IFoo. Then ask for an instance of CompositeFoo.
cfg.For<IFoo>().Add<Foo1>();
cfg.For<IFoo>().Add<Foo2>();
cfg.ForConcreteType<CompositeFoo>();
...
var result = container.GetInstance<CompositeFoo>();
Define a new interface for the composite.
interface ICompositeFoo : IFoo {}
class CompositeFoo : ICompositeFoo
...
cfg.For<IFoo>().Add<Foo1>();
cfg.For<IFoo>().Add<Foo2>();
cfg.For<ICompositeFoo>().Use<CompositeFoo>();
...
var foo = container.GetInstance<ICompositeFoo>();
After trying to accomplish this using policies or factory classes, I sacked StructureMap in favour of Grace. There I can easily instantiate the composite object with the following code
var container = new DependencyInjectionContainer();
container.Configure(c =>
{
c.Export<Foo1>().As<IFoo>();
c.Export<Foo2>().As<IFoo>();
c.Export<CompositeFoo>().As<IFoo>();
});
var foo = container.Locate<IFoo>();
foo.Do();
And the result is as expected:
foo1
foo2
The problem with StructureMap for me is that they do not support any way to specify dependencies for an object dynamically. I could make it work if I manually write all instances which should be injected or resolve all, including the composite object. I could probably make it somehow possible using policies with injected container and specify dependencies that way, but it is too hacky in my opinion.
I have the following interfaces and concrete implementations:
interface IFoo {
string Name { get ;}
}
class Foo :IFoo{
public string Name { get; set; }
}
interface IBar {
string Name { get; }
}
class Bar : IBar {
public string Name { get;set;}
public Bar(Foo foo) {
}
}
You can see that Bar has a dependency on Foo in the class constructor.
These are my bindings:
kernel.Bind<IFoo>().ToConstant(new Foo() { Name="Foo"; });
kernel.Bind<IBar>().To<Bar>();
When I use kernel.Get and ask for Bar, there are no errors, but the Foo dependency is a different instance of Foo that I originally bound. I expected to see Foo with a name of "Foo" when I inspect the Foo instance inside of the Bar constructor, but instead I see Foo { Name = null }.
When I bind to concrete Foo, everything works as expected:
var foo = new Foo() { Name="Foo" };
kernel.Bind<IFoo>().ToConstant(foo);
kernel.Bind<Foo>().ToConstant(foo);
kernel.Bind<IBar>().To<Bar>();
var bar= kernel.Get<Bar>(); // works! foo has name "Foo"
Is there a convenient way to bind a specific instance of Foo to all the available interfaces, and concrete types?
For example:
class ConcreteFoo : AbstractFoo, IFoo {
...
}
var foo = new Foo();
kernel.Bind<IFoo>().ToConstant(foo);
kernel.Bind<AbstractFoo>().ToConstant(foo);
kernel.Bind<ConcreteFoo>().ToConstant(foo);
I have a generic framework. Outside of the framework is Foo and Bar that the clients define. I want clients to have the flexibility of specifying IFoo or Foo in the Bar constructor. If the constructor was defined as Bar(IFoo), the client might be casting it to Foo anyway.
There's no such functionality provided by ninject. What ninject offers is binding to multiple types, for example:
Bind<IFoo,Foo>().To<Foo>().InSingletonScope();
Ensures no matter what combination of IFoo and Foo are requested, you always get the same Foo instance.
Then, there's Ninject.Extensions.Conventions which can look for types (like all classes of an assembly) and bind them to all their interface, all their base types,... but only either or, not both. You could use this to achieve what you want, but it would require quite some code on your end, too,.. and it would be kind of akward.
So, in my opinion, it's best just to roll your own:
using Ninject.Infrastructure.Language;
public static void RegisterConstantAsAllTypes(IBindingRoot bindingRoot, object instance)
{
Type t = instance.GetType();
IEnumerable<Type> typesToBind = t.GetAllBaseTypes()
.Concat(t.GetInterfaces())
.Except(new[] { typeof(object) });
bindingRoot
.Bind(typesToBind.ToArray())
.ToConstant(instance);
}
Given your example the following test passes:
[Fact]
public void FactMethodName()
{
var kernel = new StandardKernel();
var foo = new Foo();
RegisterConstantAsAllTypes(kernel, foo);
kernel.Get<IFoo>().Should().Be(foo);
kernel.Get<Foo>().Should().Be(foo);
kernel.Get<AbstractFoo>().Should().Be(foo);
}
I would like to configure Castle Windsor to create two components of same type (Foo -> IFoo), but with different constructor inputs. I would also later like to consume both components when creating another component (type Bar - see code below).
public interface IFoo { }
public class Foo : IFoo
{
private string _prop;
public Foo(string prop)
{
_prop = prop;
}
}
public class Bar
{
private IFoo _fooAbc;
private IFoo _foo123;
public Bar(IFoo fooAbc, IFoo foo123)
{
_foo123 = foo123;
_fooAbc = fooAbc;
}
}
In component installer I tried registering components like this:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.BasedOn<IFoo>().WithServiceBase()
.ConfigureFor<Foo>(c => c.DependsOn(Dependency.OnValue<string>("abc")).Named("fooAbc"))
.ConfigureFor<Foo>(c => c.DependsOn(Dependency.OnValue<string>("123")).Named("foo123")));
container.Register(Component.For<Bar>()); //?? specify which service to use
}
But castle throws an registration exception. So how can I configure two instances of Foo, one with "abc" and another with "123" dependency? Also I would later like to correctly assign them when constructing Bar, so that fooAbc is used as first constructor input, and foo123 as second. My end goal would be to successfully resolve Bar.
I'm not sure if this is closer to what you're asking for, but, you can use
ServiceOverride.ForKey to specify which parameters map to which names:
Component.For<Bar>().ImplementedBy<Bar>().
DependsOn(ServiceOverride.ForKey("fooAbc").Eq("abc")).
DependsOn(ServiceOverride.ForKey("foo123").Eq("123"))
);
Alternatively, not a direct answer, but an option you have is to resolve an IEnumerable<IFoo>. This is a good option if you actually have an arbitrary number of IFoo to resolve.
If you change the definition of Bar to accept an IEnumerable
public class Bar
{
private readonly IEnumerable<IFoo> _foos;
public Bar(IEnumerable<IFoo> foos)
{
_foos = foos;
}
}
Then to register and resolve. You need to add the Resolve before you do the registrations.
var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel, true));
container.Register(
Component.For<IFoo>().Instance(new Foo("abc")).Named("abc"),
Component.For<IFoo>().Instance(new Foo("123")).Named("123"),
Component.For<Bar>().ImplementedBy<Bar>());
I have global flags which enable/disable features. I'd like to inject some dependencies depending on some flag. Some features require classes which are heavily constructed so I want to inject null if the value of the flag is false and the actual dependency otherwise. Ninject doesn't allow injecting null. Are there any other options?
Update: constructor arguments can be decorated with OptionalAttribute attribute. In this case null is injected if there is no corresponding binding found. There is a problem here: I can't verify if target class can be properly constructed. I have a test for each public dependency which verifies if it can be constructed successfully. In case if the value of the flag is true I will not be able to find the error when the dependency decorated with the OptionalAttribute attribute, cannot be constructed properly. I'd like to manage it on binding level only.
You can vary the injection behaviour by binding using a factory method (i.e. ToMethod), and it's possible to allow injection of nulls by configuring the container's AllowNullInjection setting.
Another alternative would be to use a factory method and supply a lightweight dummy object instead of your heavy-weight class. If you are using interfaces this would be straightforward, just have implementations of the interface that do nothing. You could even use a mocking framework such as FakeItEasy to construct these dummies for you. The benefit here, is that the dummy makes the special behaviour transparent to clients i.e. clients do not need to check for null, etc.
An example of using a factory method, plus AllowNullInjection and nulls:
public void Configure()
{
bool create = true;
IKernel kernel = new StandardKernel();
kernel.Settings.AllowNullInjection = true;
kernel.Bind<IFoo>().ToMethod(ctx => create ? ctx.Kernel.Get<Foo>() : null);
DependendsOnIFoo depFoo = kernel.Get<DependendsOnIFoo>();
}
private interface IFoo {}
private class Foo : IFoo {}
private class DependendsOnIFoo
{
public DependendsOnIFoo(IFoo foo) {}
}
And an example where a lightweight object is substituted depending on the flag:
public void Configure()
{
bool heavy = true;
IKernel kernel = new StandardKernel();
kernel.Bind<IFoo>()
.ToMethod(ctx => heavy ? ctx.Kernel.Get<HeavyFoo>() : (IFoo)new DummyFoo());
DependendsOnIFoo depFoo = kernel.Get<DependendsOnIFoo>();
}
private interface IFoo {}
private class HeavyFoo : IFoo {}
private class DummyFoo : IFoo { }
private class DependendsOnIFoo
{
public DependendsOnIFoo(IFoo foo) {}
}
Injecting null is usually not a wise idea. This will pollute your code with checks if the object is null or not as shown by the following code:
public interface IFoo
{
void Do();
}
public class Foo : IFoo
{
public void Do()
{
DoSomething();
}
}
public class UglyNullCheckingBar
{
IFoo foo;
public Bar(IFoo foo)
{
this.foo = foo;
}
public void Do()
{
if (this.foo != null)
{
this.foo.Do();
}
}
}
The better way in this case is to implement a Null Object which does absolutely nothing and inject this one instead of null. This keeps your code clean.
public class NullFoo : IFoo
{
public void Do() {}
}
public class Bar
{
IFoo foo;
public Bar(IFoo foo)
{
this.foo = foo;
}
public void Do()
{
this.foo.Do();
}
}
I have a fairly straight-forward scenario that I am trying to solve but I'm hitting a few brick walls with Windsor - perhaps I'm trying to solve the problem in wrong way?
I have a type called Foo as follows:
public class Foo
{
[NonSerialized]
private IBar bar;
public IBar Bar
{
get { return this.bar; }
set { this.bar = value; }
}
public Foo(IBar bar)
{
}
}
I instantiate via the container in the normal way:
var myFoo = container.Resolve<Foo>();
The dependency IBar is registered with the container and gets resolved when the object is created. Now that the type has been created, I need to serialize it and I don't want to serialize IBar so it's marked with a NonSerialized attribute.
I then need to deserialize the object and return it to it's former state. How do I achieve this with Castle Windsor? I already have an instance, it is just missing it's dependencies.
If I was using Unity, I would use BuildUp() to solve the problem, but I want to use Castle Windsor in this case.
It seems like Foo is having multiple concerns. Try to separate the data part from the behavior by creating a new class for the data and use it as a property in the Foo class:
[Serializable]
public class FooData
{
}
public class Foo
{
private FooData data = new FooData();
public IBar Bar { get; private set; }
public FooData Data { get; set; }
public Foo(IBar bar)
{
}
}
When you have this construct in place you can deserialize FooData and use it in a created Foo:
var foo = container.Get<Foo>();
foo.Data = DeserializeData();