I am new to Castle Windsor and am trying to grok the basics...
I have the following code...
namespace WindowsBash.Models
{
public interface IShouter
{
string Display();
}
public class Shout : IShouter
{
private IMessage _message;
public Shout(IMessage message)
{
_message = message;
}
public string Display()
{
return _message.TheMessage();
}
}
public interface IMessage
{
string TheMessage();
}
public class MessageHello : IMessage
{
public string TheMessage()
{
return "Hello";
}
}
public class MessageBye : IMessage
{
public string TheMessage()
{
return "Bye";
}
}
}
I then have the following method to try and test what Windsor is doing....
private void TestIOC()
{
var container = new WindsorContainer();
container.Register(
AllTypes.FromAssemblyContaining<IShouter>()
.Where(x => x.Namespace.StartsWith("WindowsBash"))
.WithService.AllInterfaces());
var MyShouter = container.Resolve<IShouter>();
var result = MyShouter.Display();
}
Right now this always returns "Hello". If I wanted it to return "Bye", what would I need to change without changing the order of the classes?
I assume you want to use auto-wiring. If not, you can do manual registration for each of your components. (Edit: looks like you discovered one-by-one registration on your own :) ).
See the chosen answer for this question to use auto-wiring but control the default implementation for a specific type:
Castle Windsor: Using convention registration along with specific implementations
I came up with this that seemed to work...
private void TestIOC()
{
var container = BootstrapContainer();
container.Register(
Component.For<IShouter>().ImplementedBy<Shout>(),
Component.For<IMessage>().ImplementedBy<MessageBye>());
var shell = container.Resolve<IShouter>();
var result = shell.Display();
container.Dispose();
}
If you're using Windsor 3:
private void TestIOC()
{
var container = new WindsorContainer();
container.Register(
AllTypes.FromAssemblyContaining<IShouter>()
.Where(x => x.Namespace.StartsWith("WindowsBash"))
.WithService.AllInterfaces()
.ConfigureFor<MessageBye>(c => c.IsDefault()));
var MyShouter = container.Resolve<IShouter>();
var result = MyShouter.Display();
}
However usually if you only want one component out of several, just don't install the other ones - put in the container only what you want for that particular context.
I have seen this done in XML so you can configure it outside of compiled classes:
http://www.castleproject.org/container/documentation/v21/usersguide/externalconfig.html
You could either register them with a name, or ResolveAll and find the correct one. However, what you want to do is not really useful in real life, because when registering multiple implementations, you probably want to use all implementations.
Related
Having the following interface and their implementations...
public interface IEmpty<T> { }
public class Empty1 : IEmpty<Empty1>{ }
public class Empty2 : IEmpty<Empty2>{ }
public class EmptyN : IEmpty<EmptyN>{ }
allows me to register them and inject them explicitly into constructors
public class NewClass1 {
private IEmpty<Empty1> Empty;
public NewClass1(IEmpty<Empty1> empty)
{
Empty = empty;
}
public string EmptyType => $"{Empty.GetType()}";
}
but when I tried to resolve all implementations of 'IEmpty<>' at once...
var allIEmpties = host.Services.GetServices(typeof(IEmpty<>));
allIEmpties.ToList().ForEach(empty => Console.WriteLine(empty.GetType()));
... execution of the code threw a 'NotSupportedException' (Cannot create arrays of open type), which I kind of understand, but leaves me wondering if it can be done and how it would have to be done to get a handle on all Services implementing IEmpty.
Would anyone have an idea of how to achieve this?
My motivation to get this working is to
only register each service once (DRY)
be able to explicity inject services into constructors without the need of some resolver-pattern or named dependencies
load all implementations after startup to validate specific properties they are requried to implement due to the interfaces without having to search reflectively through all assemblies, which is my temporary solution but crawling through a box of needles to find 2 specific ones sounds wrong, if I could have a sorted box offering me direct access to the needles I need...
Using these additional nuget packages:
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Hosting
Microsoft.Extensions.Hosting.Abstractions
I have created this proof of concept snippet in LinqPad, in case you'd want to have a go:
void Main()
{
var args = new List<string>();
var host = CreateHostBuilder(args.ToArray()).Build();
var newClass = host.Services.GetService<NewClass1>();
Console.WriteLine(newClass.EmptyType);
var oneEmpty = host.Services.GetService(typeof(IEmpty<Empty2>));
Console.WriteLine(oneEmpty.GetType());
var allIEmpties = host.Services.GetServices(typeof(IEmpty<>));
allIEmpties.ToList().ForEach(empty => Console.WriteLine(empty.GetType()));
}
IHostBuilder CreateHostBuilder(string[] args)
{
var hostBuilder =
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, builder) => {
builder.SetBasePath(Directory.GetCurrentDirectory());
})
.ConfigureServices((context, services) => {
services.AddTransient<IEmpty<Empty1>, Empty1>();
services.AddTransient<IEmpty<Empty2>, Empty2>();
services.AddTransient<IEmpty<EmptyN>, EmptyN>();
services.AddTransient<NewClass1>();
});
return hostBuilder;
}
public class NewClass1 {
private IEmpty<Empty1> Empty;
public NewClass1(IEmpty<Empty1> empty)
{
Empty = empty;
}
public string EmptyType => $"{Empty.GetType()}";
}
public interface IEmpty<T> {}
public class Empty1 : IEmpty<Empty1>{ }
public class Empty2 : IEmpty<Empty2>{ }
public class EmptyN : IEmpty<EmptyN>{ }
Resolving a list of generic types based on its open-generic definition by calling GetServices(typeof(IEmpty<>)) is not supported by MS.DI. Although technically possible, there is no DI Container that I'm familiar with that actually supports this.
There are many possible ways to solve your issue. You could, for instance, introduce a non-generic IEmpty (marker) interface that IEmpty<T> inherits from.
You can also go through the code base using Reflection, as you already mentioned, or you can go through the registrations in the ServiceCollection to get all registered IEmpty<T> registrations. This list can than be used to get the list. For instance:
var emptyTypes =
from s in services
where s.ServiceType.IsGenericType
where s.ServiceType.GetGenericTypeDefinition() == typeof(IEmpty<>)
select s.ServiceType;
foreach (Type emptyType in emptyTypes)
{
var empty = host.Services.GetRequiredService(emptyType);
Console.WriteLine(empty.GetType());
}
Let's assume I have interfaces like the following:
public interface ISomething { };
public interface IResolver
{
string ResolveBy(ISomething something);
}
Now I have two resolver types; one that delivers the best solution, but has a chance to fail and one resolver, that does always return a solution, which should act as a fallback strategy:
public class UnsafeResolver : IResolver
{
Random random = new Random();
public string ResolveBy(ISomething something)
{
if (random.NextDouble() > 0.5)
{
return "best solution ever!";
}
else
{
throw new InvalidOperationException("something went wrong...");
}
}
}
public class SafeResolver : IResolver
{
public string ResolveBy(ISomething something)
{
return "fallback solution";
}
}
Now I want to combine both resolver within a safeguarded composition decorator:
public class SafeguardedResolver : IResolver
{
private readonly IResolver unsafeResolver;
private readonly IResolver safeResolver;
// This is the problem with Ninject: Two parameters with same interface...
public SafeguardedResolver(IResolver unsafeResolver, IResolver safeResolver)
{
// guards omitted!
this.unsafeResolver = unsafeResolver;
this.safeResolver = safeResolver;
}
public string ResolveBy(ISomething something)
{
try
{
return unsafeResolver.ResolveBy(something);
}
catch (InvalidOperationException)
{
return safeResolver.ResolveBy(something);
}
}
}
So my question is: How can I realize the binding with Ninject without using Named Binding Strategies? I do not want any dependencies to the container in my domain classes, so the proposed solution does not work for me 😞
And of course without changing the ctor to IEnumerable<IResolver> - I want two separate clearly named parameters!
Why is it not possible to define the binding via the names of the parameters? For example something like this:
Bind<IResolver>().To<SafeguardedResolver>();
Bind<IResolver>().To<UnsafeResolver>()
.WhenInjectedInto<SafeguardedResolver>()
.AsParameter("unsafeResolver");
Bind<IResolver>().To<SafeResolver>()
.WhenInjectedInto<SafeguardedResolver>()
.AsParameter("safeResolver");
Isn't it possible to get the names of a parameter with reflection?
I hope somebody can give me an answer, how to solve that (perhaps by using another DI framework?) or why this is impossible.
I do not want any dependencies to the container in my domain classes
You can use named bindings without referencing the container from your class library, here is how you can do it:
StandardKernel kernel = new StandardKernel();
kernel
.Bind<IResolver>()
.To<SafeguardedResolver>()
.WithConstructorArgument("unsafeResolver", c => c.Kernel.Get<IResolver>("unsafe"))
.WithConstructorArgument("safeResolver", c => c.Kernel.Get<IResolver>("safe"));
kernel
.Bind<IResolver>()
.To<UnsafeResolver>()
.Named("unsafe")
.BindingConfiguration.IsImplicit = true;
kernel
.Bind<IResolver>()
.To<SafeResolver>()
.Named("safe")
.BindingConfiguration.IsImplicit = true;
Here is how you would do the same thing with Pure DI:
var result = new SafeguardedResolver(new UnsafeResolver(), new SafeResolver());
The simplicity of Pure DI in cases like these is one of the reasons why IMO it is better than using a container.
I'm a bit tired of manually registering fake dependencies in my unit tests... I'm wondering if there is a way to configure Unity in such a way that, if there is no registered implementation for a given type, it automatically creates a fake using FakeItEasy or some other mocking framework.
So instead of writing this:
var container = new UnityContainer();
var fooProvider = A.Fake<IFooProvider>();
container.RegisterInstance(fooProvider);
var barService = A.Fake<IBarService>();
container.RegisterInstance(barService);
var bazManager = A.Fake<IBazManager>();
container.RegisterInstance(bazManager);
var sut = container.Resolve<SystemUnderTest>();
I could just write something like this:
var container = new UnityContainer();
container.AutoFake();
var sut = container.Resolve<SystemUnderTest>();
Is it possible? I was looking for some kind of callback that would be called when Unity tries to resolve a type, but I couldn't find anything. There seems to be plenty of extensibility points, with extensions, strategies, policies, call handlers and so forth, but I don't have a clue where to start...
OK, I managed to do it, using AutoMocking (thanks to Sam Holder for the link) as an example to create a Unity extension. The code is relatively simple:
public class AutoFakeExtension : UnityContainerExtension
{
protected override void Initialize()
{
Context.Strategies.AddNew<AutoFakeBuilderStrategy>(UnityBuildStage.PreCreation);
}
private class AutoFakeBuilderStrategy : BuilderStrategy
{
private static readonly MethodInfo _fakeGenericDefinition;
static AutoFakeBuilderStrategy()
{
_fakeGenericDefinition = typeof(A).GetMethod("Fake", Type.EmptyTypes);
}
public override void PreBuildUp(IBuilderContext context)
{
if (context.Existing == null)
{
var type = context.BuildKey.Type;
if (type.IsInterface || type.IsAbstract)
{
var fakeMethod = _fakeGenericDefinition.MakeGenericMethod(type);
var fake = fakeMethod.Invoke(null, new object[0]);
context.PersistentPolicies.Set<ILifetimePolicy>(new ContainerControlledLifetimeManager(), context.BuildKey);
context.Existing = fake;
context.BuildComplete = true;
}
}
base.PreBuildUp(context);
}
}
}
Example usage:
var container = new UnityContainer();
container.AddNewExtension<AutoFakeExtension>();
// The IFoo dependency is provided automatically using FakeItEasy
var test = container.Resolve<Test>();
public interface IFoo
{
}
public class Test
{
public Test(IFoo foo)
{
}
}
This implementation is probably not suitable for all use cases, but it does exactly what I need.
Unity doesn't have this out of the box, but there is a project called AutoFixture that aims to provide what you want. I'm not certain there is support for Unity out of the box, but as I understand it is possible to plug in your own containers.
This project also does something similar, but again I don't think it supports unity out of the box
I've been struggling with this problem for a couple days, and I still am not sure how to solve it.
I've created a container extension for the Unity Container to enable me to easily register decorator classes in the container. This is the implementation I currently have, which is almost identical to the one in this article:
public class DecoratorExtension : UnityContainerExtension
{
private int m_order;
private Dictionary<Type, IList<DecoratorRegistration>> m_typeStacks;
protected override void Initialize()
{
m_typeStacks = new Dictionary<Type, IList<DecoratorRegistration>>();
Context.Registering += AddRegistration;
Context.Strategies.Add(new DecoratorBuildStrategy(m_typeStacks), UnityBuildStage.PreCreation);
}
private void AddRegistration(object _sender, RegisterEventArgs _e)
{
if (_e.TypeFrom == null || !_e.TypeFrom.IsInterface)
return;
GetStack(_e.TypeFrom)
.Add(new DecoratorRegistration {Order = m_order++, Type = _e.TypeTo});
}
private IList<DecoratorRegistration> GetStack(Type _type)
{
if (!m_typeStacks.ContainsKey(_type))
m_typeStacks.Add(_type, new List<DecoratorRegistration>());
return m_typeStacks[_type];
}
}
What this does is use a list for each type, to store all type registrations for the same target type, so that I can reassemble it when Resolve is called, using this build strategy:
internal class DecoratorBuildStrategy : BuilderStrategy
{
private readonly Dictionary<Type, IList<DecoratorRegistration>> m_typeStacks;
internal DecoratorBuildStrategy(Dictionary<Type, IList<DecoratorRegistration>> _typeStacks)
{
m_typeStacks = _typeStacks;
}
public override void PreBuildUp(IBuilderContext _context)
{
var key = _context.OriginalBuildKey;
if (_context.GetOverriddenResolver(key.Type) != null)
return;
// Only interfaces can use decorators.
if (!key.Type.IsInterface)
return;
// Gets the list of types required to build the 'decorated' instance.
// The list is reversed so that the least dependent types are built first.
var decoratorTypes = GetDecoratorTypes(key.Type).Reverse().ToList();
if (!decoratorTypes.Any())
return;
object value = null;
foreach (var type in decoratorTypes)
{
Type typeToBuild = type;
if (typeToBuild.IsGenericTypeDefinition)
{
Type[] genericArgumentTypes = key.Type.GetGenericArguments();
typeToBuild = typeToBuild.MakeGenericType(genericArgumentTypes);
}
value = _context.NewBuildUp(new NamedTypeBuildKey(typeToBuild, key.Name));
// An Override is created so that in the next BuildUp the already
// built object gets used instead of doing the BuildUp again and
// entering an infinite loop
_context.AddResolverOverrides(new DependencyOverride(key.Type, value));
}
_context.Existing = value;
_context.BuildComplete = true;
}
private IEnumerable<Type> GetDecoratorTypes(Type _type)
{
var typeList = m_typeStacks.GetValueOrDefault(_type) ?? new List<DecoratorRegistration>(0);
if (!_type.IsGenericType)
return typeList.Select(_reg => _reg.Type);
// If the type is a generic type, we need to get all open generic registrations
// alongside the closed ones
var openGenericList = m_typeStacks
.GetValueOrDefault(_type.GetGenericTypeDefinition()) ??
new List<DecoratorRegistration>(0);
// The final result is an ordered concatenation of the closed and open registrations
// that should be used for the type
return typeList
.Concat(openGenericList)
.OrderBy(_registration => _registration.Order)
.Select(_reg => _reg.Type);
}
}
This is where the DecoratorRegistration model is used. It is just a pair of type/int that represents the order of the registration. I created this to be able to mix open and closed generic registrations correctly:
internal struct DecoratorRegistration
{
public int Order { get; set; }
public Type Type { get; set; }
}
This works wonders for the most part. The problem started when I had a class that implemented two interfaces, one which was decorated, and one that wasn't.
This is the current test case I'm trying to make work:
private interface IAny<T> {}
private interface IAnotherInterface {}
private class Base<T> : IAnotherInterface, IAny<T> {}
private class Decorator1<T> : IAny<T>
{
internal readonly IAny<T> Decorated;
public Decorator1(IAny<T> _decorated)
{
Decorated = _decorated;
}
}
[TestMethod]
public void DecoratorExtensionDoesNotInterfereWithNormalRegistrations()
{
// Arrange
var container = new UnityContainer()
.AddNewExtension<DecoratorExtension>()
.RegisterType<Base<string>>(new ContainerControlledLifetimeManager())
.RegisterType<IAny<string>, Decorator1<string>>()
.RegisterType<IAny<string>, Base<string>>()
.RegisterType<IAnotherInterface, Base<string>>();
// Act
var decorated = container.Resolve<IAny<string>>();
var normal = container.Resolve<IAnotherInterface>();
var anotherDecorated = container.Resolve<IAny<string>>();
var anotherNormal = container.Resolve<IAnotherInterface>();
// Assert
Assert.IsInstanceOfType(normal, typeof (IAnotherInterface));
Assert.IsInstanceOfType(decorated, typeof (Decorator1<string>));
Assert.AreSame(normal, anotherNormal);
Assert.AreSame(decorated, anotherDecorated);
}
This test should make my intent clear. I wanted singleton classes, but the first call to Resolve, for either IAnotherInterface or IAny<string> results in every subsequent call to return the same thing. Thus, I get an exception:
System.InvalidCastException: Unable to cast object of type 'Decorator1`1[System.String]' to type 'IAnotherInterface'.
on this line:
var normal = container.Resolve<IAnotherInterface>();
I'm not sure what to do here. I had to temporarily disable singletons in our project so that this could work as intended. What I wanted is that the Base<string> instance was a sintleton, but when I requested a IAny<string> it would create a NEW instance with the SAME base being decorated.
This is still using .Net 4.0, so I'm stuck with Unity 2.1 here (shouldn't matter in this case though).
It's been a while since I've solved this, so I figured that it would be good to replicate the answer I got from Randy Levy from the EntLib team here.
It basically boils down to the build key I was using to register the decorator instance. With my code, the instance was actually registered with the base class type, while I needed to register it with the actual decorator type.
This post has the suggested workaround for the issue, which worked very nicely on our end.
I'm not exactly sure if this is what you're looking for, but I think this does the trick in the specific case in your test:
container.RegisterType<IAny<string>, Base<string>>(
new ContainerControlledLifetimeManager(), "Inner");
container.RegisterType<IAny<string>, Decorator1<string>>(
new InjectionConstructor(
new ResolvedParameter(typeof(IAny<string>), "Inner")));
container.Register<IAnotherInterface>(new InjectionFactory(
c => c.Resolve<IAny<string>>("Inner")));
You don't need that extension for that.
I have the following classes:
public interface IRenderer<T>
{
string Render(T obj);
}
public class Generic<T> { }
public class SampleGenericRenderer<T> : IRenderer<Generic<T>>
{
public string Render(Generic<T> obj)
{
throw new NotImplementedException();
}
}
I would like to be able to call StructureMap with
ObjectFactory.GetInstance<IRenderer<Generic<string>>>(); and receive SampleGenericRenderer<string>.
I'm currently using the following registration and receiving this error when I call GetInstance. "Unable to cast object of type:
ConsoleApplication1.SampleGenericRenderer'1[ConsoleApplication1.Generic'1[System.String]]'
to type
'ConsoleApplication1.IRenderer'1[ConsoleApplication1.Generic'1[System.String]].
public class CoreRegistry : Registry
{
public CoreRegistry()
{
Scan(assemblyScanner =>
{
assemblyScanner
.AssemblyContainingType(typeof(IRenderer<>));
assemblyScanner.AddAllTypesOf(typeof(IRenderer<>));
assemblyScanner
.ConnectImplementationsToTypesClosing(
typeof(IRenderer<>));
});
}
}
Is there any way to configure StructureMap so that it creates SampleGenericRenderer<string> instead of SampleGenericRenderer<Generic<string>>?
UPDATE: I ended up doing the type construction myself for this subset of dependencies. Because they combine contextual binding with a lot of unsupported generic bindings, this turned out to be the cleanest solution.
As Pete explained, there is probably no way with StructureMap to do this. Other DI containers might yield more success, but not all contains have great support for more complex generic trickery. The only one I know for sure that allows you to do this is the Simple Injector. With the Simple Injector, you just need the following configuration:
var container = new Container();
container.Register(typeof(IRenderer<>), typeof(SampleGenericRenderer<>));
// Usage
var renderer = container.GetInstance<IRenderer<Generic<string>>>();
renderer.Render(new Generic<string>());
More info about this method can be found here.
I don't believe StructureMap has any mechanism for closing an inner generic parameter like this.
It's not ideal, but you might try creating your own IRegistrationConvention and whenever encountering a type that is a closed type of Generic<>, do the following:
var generic_t = typeof(Generic<>).MakeGenericType(type);
var sample_renderer_t = typeof(SampleGenericRenderer<>).MakeGenericType(type);
var renderer_t = typeof(IRenderer<>).MakeGenericType(generic_t);
graph.AddType(renderer_t, sample_renderer_t);
See http://docs.structuremap.net/ScanningAssemblies.htm#section11 for more details.
For me this works:
class Program
{
static void Main()
{
ObjectFactory.Configure(x=>x.AddRegistry<CoreRegistry>());
var instance = ObjectFactory.GetInstance(typeof(IRenderer<string>)) as IRenderer<Generic<string>>;
var render = instance.Render(new Generic<string>());
}
}
This throws an exception:
ObjectFactory.GetInstance<IRenderer<Generic<string>>>();
What is your real problem?
EDIT:
Under some circumstances this could work too (If you don't know Generic<string> at design time):
static void Main()
{
ObjectFactory.Configure(x => x.AddRegistry<CoreRegistry>());
var instance = ObjectFactory.GetInstance(typeof(IRenderer<string>));
var methodInfo = instance.GetType().GetMethod("Render");
methodInfo.Invoke(instance, new[] { new Generic<string>() });
}