How does Castle Windsor respond to a class which implements multiple interfaces? - inversion-of-control

For example I have two interfaces: ICustomerService and IOrderService which each has a couple of functions like GetCustomer, GetOrder, etc.
I want one class to implement both interfaces: Server.
How does Castle Windsor respond to this?
Is it possible in the first place?
When I resolve the Server object based on one of the two interfaces, will I get the same object?
What happens when I have a constructor that has both interfaces in its parameters? Will there still be one object constructed.
assuming the LifeStyle is left to its default: Singleton.

There's no hard one-to-one mapping between a CLR type and a Windsor service or component (glossary if needed is here).
So you can have any of the following scenarios:
Many Components with different implementation types expose a single Service
container.Register(
Component.For<IFoo>().ImplementedBy<Foo1>(),
Component.For<IFoo>().ImplementedBy<Foo2>()
);
Many Components with same implementation type expose a single Service
container.Register(
Component.For<IFoo>().ImplementedBy<Foo1>(),
Component.For<IFoo>().ImplementedBy<Foo1>().Named("second")
);
Many Components with same implementation type expose different Services
container.Register(
Component.For<IFoo>().ImplementedBy<Foo1>(),
Component.For<IBar>().ImplementedBy<Foo1>().Named("second")
);
Single Component expose different Services
container.Register(
Component.For<IFoo, Bar>().ImplementedBy<Foo1>()
);
As you can see, yes - it is possible, and whether or not you'll get the same instance (assuming singleton) depends on which option you chose - if both Services will be exposed by the same Component, or not.

Related

Using Zenject to inject an implementation with interfaces

I'm trying to use Zenject in Unity. I have an interface and several implementations of it.
I want to inject with ID but also that the implementation will have the tick interface since it's not a MonoBehaviour.
So I have an IAttacker interface and a MeleeAttackImpl implementation.
Container.Bind<IAttacker>().WithId(AttackerTypeEnum.MELEEE).To<MeleeAttackImpl>().AsTransient();
I want to add
Container.BindInterfacesTo<MeleeAttackImpl>().AsTransient();
But it creates 2 different objects instead of instances that have the Tick interface and bind them to IAttacker.
If you want to bind an interface to a determined implementation, why do you use two bindings?
If you want only one instance of the object I would try:
Container.BindInterfacesAndSelfTo<MeleeAttackImpl>().AsSingle();
or:
Container.Bind<IAttacker>().To<MeleeAttackImpl>().AsSingle();
As Single() In the case you need the same instance provided from the container along the app (like a singleton).
From the documentation:
"AsTransient - Will not re-use the instance at all. Every time ContractType is requested, the DiContainer will execute the given construction method again."
Many times intance is created in the binding itself. So maybe from the two binding two instances are created, one from each binding.
In case you need to create instances dynamically with all their dependencies resolved, what you need a is Factory.

Multiple IActor interfaces

I have a need for an Actor to implement multiple interfaces. Is this possible?
Currently, when I attempt to have the Actor type implement an interface that derives from another interface which derives from IActor, I get a message that it implements multiple interfaces, and ActorServiceAttribute needs to be used to distinguish. Adding ActorServiceAttribute does not remove the error message.
[EDIT]
I believe I solved this problem. The errors are confusing. You need to directly implement BOTH interfaces on the Actor type. The build-time discover does not seem to enumerate through the interface hierarchy to find IActor.
Thanks for reporting the issue. Can you provide information on your interface hierarchy. Adding the ActorServiceAttribute on the actor with the valid service name should have resolved the error. By default the actor services are named using the actor interfaces. In this case since there are two different actor interfaces (IBaseActor, IDerivedActor) that are implemented by the actor, runtime cannot determine the naming for the actor service. This is because on the client side, one can create ActorProxy or ActorProxy.

Is there a way to configure Autofac to create inheritors of some base class to be single instances?

I am using Prism with Autofac, and I found myself couple of times having a bugs due to multiple instances of the ViewModel class which I expected to be single instance.
Thus my question is: how can I configure Autofac so that all inheritors from some base class (e.g. ViewModelBase) will always be single instances?
That's very easy to do with container builder extension methods. This is one way
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.AssignableTo<ViewModelBase>()
.SingleInstance();

What does kernel.Bind<SomeType>().ToSelf() do?

I understand the following Ninject registration:
kernel.Bind<ISomeType>().To<SomeTypeImplementation>();
which tells Ninect to fulfill requests for ISomeType by using SomeTypeImplementation.
However I'm not sure what the following is good for.
kernel.Bind<ApplicationDbContext>().ToSelf();
Which was suggested that I use from this question:
What ninject binding should I use?
It makes ApplicationDbContext "self-bindable". If you don't have an interface to bind to, you can bind to the class itself. It's more useful if you add a scope to the call such as:
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
Any time it sees the ApplicationDbContext that needs to be injected, it will reuse the same object as long as it is in the same HTTP request.
The default scope is transient, which means that any time a class requests ApplicationDbContext it will create a new instance of it. This can be problematic if you have two classes that both need to use the context in the same transaction. That is why you will often see it done with InRequestScope().
By self-binding a type, you enable that type for the following:
Lifecycle Management by the container.
Enable the container to inject dependencies into other types that depend on the self-bound type, and inject dependencies of this type into its instances likewise.
Very useful if you just have one single implementation or you don't need to use abstractions for some reason.

Is there any reason to not use my IoC as a general Settings Repository?

Suppose that the ApplicationSettings class is a general repository of settings that apply to my application such as TimeoutPeriod, DefaultUnitOfMeasure, HistoryWindowSize, etc... And let's say MyClass makes use of one of those settings - DefaultUnitOfMeasure.
My reading of proper use of Inversion of Control Containers - and please correct me if I'm wrong on this - is that you define the dependencies of a class in its constructor:
public class MyClass {
public MyClass(IDataSource ds, UnitOfMeasure default_uom) {...}
}
and then call instantiate your class with something like
var mc = IoC.Container.Resolve<MyClass>();
Where IDataSource has been assigned a concrete implementation and default_uom has been wired up to instantiate from the ApplicationSettings.DefaultUnitOfMeasure property. I've got to wonder however, if all these hoops are really that necessary to jump through. What trouble am I setting myself up for should I do
public class MyClass {
public MyClass(IDataSource ds) {
UnitOfMeasure duom = IoC.Container.Resolve<UnitOfMeasure>("default_uom");
}
}
Yes, many of my classes end up with a dependency on IoC.Container but that is a dependency that most of my classes will have anyways. It seems like I maybe should make full use of it as long as the classes are coupled. Please Agile gurus, tell me where I'm wrong.
IoC.Container.Resolve("default_uom");
I see this as a classic anti-pattern, where you are using the IoC container as a service locater - the key issues that result are:
Your application no longer fails-fast if your container is misconfigured (you'll only know about it the first time it tries to resolve that particular service in code, which might not occur except for a specific set of logic/circumstances).
Harder to test - not impossible of course, but you either have to create a real (and semi-configured) instance of the windsor container for your tests or inject the singleton with a mock of IWindsorContainer - this adds a lot of friction to testing, compared to just being able to pass the mock/stub services directly into your class under test via constructors/properties.
Harder to maintain this kind of application (configuration isn't centralized in one location)
Violates a number of other software development principles (DRY, SOC etc.)
The concerning part of your original statement is the implication that most of your classes will have a dependency on your IoC singleton - if they're getting all the services injected in via constructors/dependencies then having some tight coupling to IoC should be the exception to the rule - In general the only time I take a dependency on the container is when I'm doing something tricky i.e. trying to avoid a circular dependency problems, or wish to create components at run-time for some reason, and even then I can often avoid taking a dependency on anything more then a generic IServiceProvider interface, allowing me to swap in a home-bake IoC or service locater implementation if I need to reuse the components in an environment outside of the original project.
I usually don't have many classes depending on my IoC container. I usually try to wrap the IoC stuff in a facade object that I inject into other classes, usually most of my IoC injection is done only in the higher layers of my application though.
If you do things your way you can't test MyClass without creating a IoC configuration for your tests. This will make your tests harder to maintain.
Another problem is that you're going to have powerusers of your software who want to change the configuration editing your IoC config files. This is something I'd want to avoid. You could split up your IoC config into a normal config file and the IoC specific stuff. But then you could just as well use the normal .Net config functionality to read the configuration.
Yes, many of my classes end up with a dependency on IoC.Container but that is a dependency that most of my classes will have anyways.
I think this is the crux of the issue. If in fact most of your classes are coupled to the IoC container itself chances are you need to rethink your design.
Generally speaking your app should only refer to the container class directly once during the bootstrapping. After you have that first hook into the container the rest of the object graph should be entirely managed by the container and all of those objects should be oblivious to the fact that they were created by an IoC container.
To comment on your specific example:
public class MyClass {
public MyClass(IDataSource ds) {
UnitOfMeasure duom = IoC.Container.Resolve<UnitOfMeasure>("default_uom");
}
}
This makes it harder to re-use your class. More specifically it makes it harder to instantiate your class outside of the narrow usage pattern you are confining it to. One of the most common places this will manifest itself is when trying to test your class. It's much easier to test that class if the UnitOfMeasure can be passed to the constructor directly.
Also, your choice of name for the UOM instance ("default_uom") implies that the value could be overridden, depending on the usage of the class. In that case, you would not want to "hard-code" the value in the constructor like that.
Using the constructor injection pattern does not make your class dependent on the IoC, just the opposite it gives clients the option to use the IoC or not.