Skip to content

Instantly share code, notes, and snippets.

@jamesmanning
Last active December 11, 2015 05:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesmanning/4549677 to your computer and use it in GitHub Desktop.
Save jamesmanning/4549677 to your computer and use it in GitHub Desktop.
using System;
using System.Linq;
using Ninject;
using Ninject.Extensions.Factory;
namespace SomeRootNamespace
{
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel();
// make sure all the necessary bindings for the implementation classes are registered
kernel.Bind<IFoo>().To<Gen1.Foo>();
kernel.Bind<IFoo>().To<Gen2.Foo>();
kernel.Rebind<IFooFactory>().To<FooFactoryManual>();
TestFooFactory(kernel);
kernel.Rebind<IFooFactory>().ToFactory(() => new NamespaceBasedProvider(kernel));
TestFooFactory(kernel);
}
private static void TestFooFactory(StandardKernel kernel)
{
var factory = kernel.Get<IFooFactory>();
factory.CreateFoo(ImplementationGeneration.Gen1).DoStuff();
factory.CreateFoo(ImplementationGeneration.Gen2).DoStuff();
try
{
factory.CreateFoo(ImplementationGeneration.Gen3).DoStuff();
throw new InvalidOperationException("Gen3 attempt should have failed");
}
catch (Exception)
{
Console.WriteLine("Gen3 correctly failed");
}
}
}
public enum ImplementationGeneration
{
Gen1,
Gen2,
Gen3,
}
public interface IFoo
{
void DoStuff();
}
public interface IFooFactory
{
IFoo CreateFoo(ImplementationGeneration implementationGeneration);
}
public class FooFactoryManual : IFooFactory
{
public IFoo CreateFoo(ImplementationGeneration implementationGeneration)
{
switch (implementationGeneration)
{
case ImplementationGeneration.Gen1:
return new Gen1.Foo();
case ImplementationGeneration.Gen2:
return new Gen2.Foo();
default:
throw new InvalidOperationException("Unsupported implementationGeneration value: " + implementationGeneration);
}
}
}
public class NamespaceBasedProvider : StandardInstanceProvider
{
private readonly IKernel _kernel;
public NamespaceBasedProvider(IKernel kernel)
{
_kernel = kernel;
}
public override object GetInstance(Ninject.Extensions.Factory.Factory.IInstanceResolver instanceResolver, System.Reflection.MethodInfo methodInfo, object[] arguments)
{
var implementationNamespaceToUse = arguments.Single().ToString();
// EVIL - DO NOT USE THIS - IT INSTANTIATES ALL POSSIBLE INSTANCES UNNECESSARILY
var allInstances = _kernel.GetAll(methodInfo.ReturnType);
var instanceToUse = allInstances.FirstOrDefault(x => x.GetType().Namespace.EndsWith(implementationNamespaceToUse));
return instanceToUse;
}
}
}
namespace SomeRootNamespace.Gen1
{
public class Foo : IFoo
{
public void DoStuff()
{
Console.WriteLine("Doing Type1 stuff");
}
}
}
namespace SomeRootNamespace.Gen2
{
public class Foo : IFoo
{
public void DoStuff()
{
Console.WriteLine("Doing Type2 stuff");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment