Castle Windsor Dependency Injection - restore dependencies for existing instance - c#

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();

Related

IoC using Autofac: How to new up during runtime?

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?).

C# dapper map to interface

Can i use C# dapper to do something like this:
IFoo bar = _dbConnection.Query<IFoo>("My query there");
Now I can't do it, due to not impelemented default parameterless constructor.
Is there some trick to honor gods of SOLID (especially spirits of Liskov Substitution Principle) or should i leave it as it is and map my data not to IFoo but to Foo?
I'm really worrying about respecting these SOLID stuff, but still don't know where i should do it, so looking for an advice for this concrete situation.
You need a concrete implementation of your class to instantiate. Internally, it has to do a create a new object. You can't create a new instance of an interface:
var foo = new IFoo(); // This won't build!
You can still cast your result to an interface, but you need a concrete type to build from the database.
IEnumerable<IFoo> foo = _dbConnection.Query<Foo>("My query there");
One way to organise repository is to use private class objects for querying, but expose results as public interfaces.
Pulbic Model:
namespace MyProject.Foo.Model
{
public interface IFoo
{
string Property1 { get; set; }
string Property2 { get; set; }
}
public interface IFooRepository
{
IEnumerbale<IFoo> GetFoos();
}
}
Query implementation with private class:
namespace MyProject.Foo.Repositories
{
public class FooRepository: IFooRepository
{
private class Foo: IFoo
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
public IEnumerbale<IFoo> GetFoos()
{
IEnumerable<IFoo> foo = _dbConnection.Query<Foo>("My query there");
return foo;
}
}
}

Is there an easy way to bind all available types to a concrete instance

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);
}

StackOverflow exception when using Fallback with Create in LightInject 3.0.2.5

This is a copy of https://github.com/seesharper/LightInject/issues/173
I tried to automatically create concrete types using fallback and .Create() but it somehow loops itself and I don't understand why.
Here is my test code:
public class Foo
{
public Foo(IBar bar, IBar2 bar2)
{
}
}
public interface IBar2
{
}
class Bar2 : IBar2
{
}
public interface IBar
{
}
class Bar : IBar
{
}
private ServiceContainer container = new ServiceContainer();
container.RegisterFallback((t, s) => true, Factory);
container.Register<IBar, Bar>();
container.Register<IBar2, Bar2>();
var foo = container.GetInstance<Foo>(); // Error here
private object Factory(ServiceRequest req)
{
return container.Create(req.ServiceType);
}
Could you please advise?
It loops even if the Factory method looks like this:
private object Factory(ServiceRequest req)
{
container.Register(typeof(Foo));
return container.GetInstance<Foo>();
}
but works perfectly if I register Foo beforehand (which I obviously want to avoid)
container.Register(typeof(Foo));
var foo = container.GetInstance<Foo>(); //ok
I am the author of LightInject and the issue has been updated with a workaround that enables the container to resolve unregistered concrete classes.
https://github.com/seesharper/LightInject/issues/173
It's the bug that was confirmed in https://github.com/seesharper/LightInject/issues/173 and is looked after by author

How to register same class twice with different dependencies

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>());

Categories