Auto-generating implementation of interface (proxy without class) - c#

What I would like to achieve is:
[Factory]
public interface IFooFactory
{
Foo Create();
}
unityContainer.RegisterType<IFooFactory>(
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<FactoryInterceptionBehavior>());
Where there is no implementation of IFooFactory - because it's provided by FactoryInterceptionBehavior.
When i try to resolve the IFooFactory however, i get a ResolutionFailedException with message:
InvalidOperationException - The current type, IFooFactory, is an
interface and cannot be constructed. Are you missing a type mapping?
I also thought about creating the proxy myself (using Intercept.ThroughProxy<> or castle dynamic proxy...), but I still need to do type registration with the container. I don't know how to delegate/override the instantiation of such a type (like Ninject's Bind<IFoo>().ToMethod(() => return new Foo())).

So after some research and trial & error i've found out, that the Unity.Interception does not support proxies of interfaces where there is no actual class implementing the interface and where invocations finally end up (castle dynamic proxies calls them "interface proxy without target").
So what i did is using is Castle.Core dynamic proxy in conjunction with unity's out-of-the-box InjectionFactory (which can be used to delegate resolution to a Func factory).
The Injection Factory looks like this:
var proxyFuncFactory = new InjectionFactory(CreateProxy);
private static object CreateProxy(IUnityContainer container, Type interfaceType, string name)
{
var proxyGenerator = container.Resolve<Castle.DynamicProxy.ProxyGenerator>();
return proxyGenerator.CreateInterfaceProxyWithoutTarget(interfaceType, container.Resolve<AutoGeneratedFactoryInterceptor>());
}
and can be used in a binding like this:
IUnityContainer.RegisterType<ISomeFactory>(proxyFuncFactory);
The AutoGeneratedFactoryInterceptor looks like:
internal class AutoGeneratedFactoryInterceptor : IInterceptor
{
private readonly IUnityContainer _unityContainer;
public AutoGeneratedFactoryInterceptor(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
public void Intercept(IInvocation invocation)
{
IEnumerable<ResolverOverride> resolverOverrides = DetermineResolverOverrides(invocation);
Type typeToResolve = DetermineTypeToResolve(invocation.Method);
invocation.ReturnValue = _unityContainer.Resolve(typeToResolve, resolverOverrides.ToArray());
}
private static Type DetermineTypeToResolve(MethodInfo method)
{
ResolveToAttribute resolveToAttribute = method.Attribute<ResolveToAttribute>();
if (resolveToAttribute == null)
{
return method.ReturnType;
}
if (resolveToAttribute.ResolveTo.IsGenericTypeDefinition)
{
return resolveToAttribute.ResolveTo.MakeGenericType(method.GetGenericArguments());
}
return resolveToAttribute.ResolveTo;
}
private static IEnumerable<ResolverOverride> DetermineResolverOverrides(IInvocation invocation)
{
return invocation.Method.Parameters()
.Select((parameterInfo, parameterIndex) =>
new ParameterOverride(parameterInfo.Name, invocation.Arguments[parameterIndex]));
}
It matches factory-method-argument to constructor-arguments by name (Unity out-of-the-box ParameterOverride). Note, that especially the generic parameter support is not perfect. It supports the following usages:
public interface IFooFactory
{
Foo Create();
}
and
unityContainer.RegisterType(typeof(IFoo<>), typeof(Foo<>));
public interface IFooFactory
{
IFoo<T> Create<T>();
}
and
public interface IFooFactory
{
Foo Create(string parameter1, object parameter2);
}
and
public interface IFooFactory
{
[ResolveTo(typeof(Foo))]
IFoo Create();
}
as well as
public interface IFooFactory
{
[ResolveTo(typeof(Foo<>))]
IFoo Create<T>();
}
Also note, that any constructor-arguments of the resolved (created) instance that are not covered by ParameterOverride's are ctor-inject "as usual".

Related

Factory method that returns generic instance

I have a base service class with virtual method that sets the properties of an object and returns that object.
Then i have one more service which derived from the base service and also overrides the base method. In overriden method, the derived service executes base.DowWork() to set common properties, and then also sets additional properties.
So based on articles here and here I was able to do this using generics.
public interface IResult
{
}
public class BaseResult : IResult
{
public string CommonProperties { get; set; }
}
public class AdditionalResult : BaseResult
{
public string AdditionalProperties { get; set; }
}
public interface IService<T> where T : IResult
{
T DoWork();
}
public class BaseService<T> : IService<T> where T : BaseResult, new()
{
public virtual T DoWork()
{
var t = new T();
t.CommonProperties = "Some Value";
return t;
}
}
public class AdditionalService : BaseService<AdditionalResult>
{
public override AdditionalResult DoWork()
{
var addtionalResult = base.DoWork();
addtionalResult.CommonProperties = "Override value that was set by BaseService";
addtionalResult.AdditionalProperties = "Set additional properties";
return addtionalResult;
}
}
So far so good
Now i want to create a Factory method that will return the instance of a service based on some type. The application will use the factory to get service instance and call DoWork() like below
class Program
{
static void Main()
{
var factory = new MyFactory();
var service = factory.GetService(0);
var iresult = service.DoWork();
// do something here with IResult
}
}
below is the factory method
public class MyFactory
{
public IService<IResult> GetService(int someType)
{
if (someType == 0)
{
return (IService<IResult>)new BaseService<BaseResult>();
}
if (someType == 1)
{
return (IService<IResult>)new AdditionalService();
}
// note I may have more types and services here. But for simplicity i am using only 2
throw new NotSupportedException();
}
}
However i am not able to figure out what should be the signature of this factory method? Based on suggestions here I'm casting service instance but while executing the application I am getting runtime exception
Unable to cast object of type
'BaseService 1[BaseResult]' to
type 'IService 1[IResult]'
if i don't cast the service instance in the Factory then i get compile time error
Cannot implicitly convert type 'BaseService' to
'IService'. An explicit conversion exists (are you missing a
cast?)
See SO question Understanding Covariant and Contravariant interfaces in C#.
You want to use covariance (out keyword). If you add it to your IService interface generic type it works as expected.
public interface IService<out T> where T : IResult
I know SO prefers not to post links but I can't possibly write anything more or better than already answered in that question.

Registering Method on Generic Factory with StructureMap

I am trying to use a method on a generic factory class in my structuremap registry. Normally, i would use the following when registering a type using a factory method:
For<Foo>().Use(x => new FooFactory().GetFoo());
And the following when registering a generic type:
For(typeof(ISomeGeneric<>)).Use(typeof(SomeGeneric<>));
How can I combine the two and retrieve a generic type from a generic factory method? I think it should be something like:
For(typeof(IFoo<>)).Use(typeof(x => new FooFactory<>().Create(someParameter));
This just gives a
"Cannot convert lambda expression to type object because it is not a delegate type"
error. I've tried various combinations but am stumped. Any ideas?
Thanks.
This is possible, BUT I would look for an alternative if you can. The issue is that to work with the open generic, you have to use some reflection. This means you will take a performance hit.
public class FooRegistry:Registry
{
public FooRegistry()
{
For(typeof(IFoo<>)).Use(x =>
{
var ParamType = x.BuildStack.Current.RequestedType
.GetGenericArguments()[0];
return BuildUsingFooFactory(ParamType);
});
}
private object BuildUsingFooFactory(Type paramType)
{
var factoryType = typeof (FooFactory<>).MakeGenericType(new[] {paramType});
var createMethod = factoryType.GetMethod("Create");
object factory = Activator.CreateInstance(factoryType);
return createMethod.Invoke(factory, new[] {"SomeParameterString"});
}
}
public class FooFactory<T>
{
public IFoo<T> Create(string param)
{
return new Foo<T>();
}
}
public interface IFoo<T>
{
}
public class Foo<T> : IFoo<T>
{
}
What you are doing in order is the following:
Find out what the requested generic argument is. (ParamType)
Create a non-open generic type for the factory (factoryType)
Grab the create method off of it. (createMethod)
Create an instance of the factory using the Activator (factory)
Call the create method on the factory instance with your some parameter.
StructureMap takes care of casting the output to the right interface.
Better Solution
Instead of using the IFoo directly, use the IFooFactory. This makes it much cleaner, you have an open generic mapping to the IFooFactory<>. Then just get the type of FooFactory you need to generate your objects.
public class FooRegistry:Registry
{
public FooRegistry()
{
For(typeof (IFooFactory<>))
.Use(typeof (FooFactory<>))
.CtorDependency<string>("connection")
.Is("SomeConnectionString");
}
}
public interface IFooFactory<T>
{
IFoo<T> CreateInstance();
}
public class FooFactory<T> : IFooFactory<T>
{
public FooFactory(string connection)
{
}
public IFoo<T> CreateInstance()
{
return new Foo<T>();
}
}
public interface IFoo<T>
{
}
public class Foo<T> : IFoo<T>
{
}

How to resolve collection with filtering parameter?

Can Castle Windsor resolve a collection filtered by a string parameter?
interface IViewFactory
{
IView[] GetAllViewsInRegion(string regionName);
}
My application defines regions as groups of IView-derived types. When I display a particular region at runtime, I want to resolve an instance of every IView type within it (a la Prism).
I've tried doing it with the Castle's Typed Factory Facility, ComponentModel Construction Contributors, and Handler Selectors, but I can't figure out how to map multiple types to a string in a way that Castle can access, nor how to extend Castle to check the string when it decides which types to try to resolve and return in the container.
Is selection by string strictly necessary? Would it be possible to instead have all IView implementations in the same "region" implement a dedicated interface that derives from IView? Then you could use WindsorContainer.ResolveAll() (passing your region-specific IView as T) to resolve the implementations for the region in question (or you could use one of the Collection Resolvers to perform constructor injection).
In general, when trying to do things like this with Windsor, I make every effort to use the type system (and Windsor's support thereof) before resorting to string-based solutions.
Update: since we confirmed that selection by string is necessary in this case, the best solution I see is to simply inspect the list of handlers in the kernel that satisfy the IView service, then filter for the implementers where the region (defined via attribute) matches what we want, then resolve those implementers. This feels a bit hackish, but if you're okay with having a direct reference to the container in your IViewFactory implementation, this appears to work fine. Below is a passing test case demonstrating the solution.
[Test]
public void Test()
{
using (var factory = new ViewFactory())
{
var regionOneViews = factory.GetAllViewsInRegion("One");
Assert.That(regionOneViews, Is.Not.Null);
Assert.That(regionOneViews, Has.Length.EqualTo(2));
Assert.That(regionOneViews, Has.Some.TypeOf<RegionOneA>());
Assert.That(regionOneViews, Has.Some.TypeOf<RegionOneB>());
var regionTwoViews = factory.GetAllViewsInRegion("Two");
Assert.That(regionTwoViews, Is.Not.Null);
Assert.That(regionTwoViews, Has.Length.EqualTo(1));
Assert.That(regionTwoViews, Has.Some.TypeOf<RegionTwoA>());
}
}
}
public interface IViewFactory
{
IView[] GetAllViewsInRegion(string regionName);
}
public class ViewFactory : IViewFactory, IDisposable
{
private readonly WindsorContainer _container;
public ViewFactory()
{
_container = new WindsorContainer();
_container.Register(
Component.For<IView>().ImplementedBy<RegionOneA>(),
Component.For<IView>().ImplementedBy<RegionOneB>(),
Component.For<IView>().ImplementedBy<RegionTwoA>()
);
}
public IView[] GetAllViewsInRegion(string regionName)
{
return _container.Kernel.GetHandlers(typeof (IView))
.Where(h => IsInRegion(h.ComponentModel.Implementation, regionName))
.Select(h => _container.Kernel.Resolve(h.ComponentModel.Name, typeof (IView)) as IView)
.ToArray();
}
private bool IsInRegion(Type implementation,
string regionName)
{
var attr =
implementation.GetCustomAttributes(typeof (RegionAttribute), false).SingleOrDefault() as RegionAttribute;
return attr != null && attr.Name == regionName;
}
public void Dispose()
{
_container.Dispose();
}
}
public interface IView {}
[Region("One")]
public class RegionOneA : IView {}
[Region("One")]
public class RegionOneB : IView {}
[Region("Two")]
public class RegionTwoA : IView {}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class RegionAttribute : Attribute
{
private readonly string _name;
public RegionAttribute(string name)
{
_name = name;
}
public string Name
{
get { return _name; }
}
}

How to easily manage adapters and/or decorators with runtime parameters?

I will give very simple example.
class Implementation: IMyInterface
{
string mArg;
public Implementation(string arg)
{
mArg = arg;
}
public DoStuff(object param)
{
// snip
}
}
class Decorator: IMyInterface
{
IMyInterface mWrapped;
public Decorator(IMyInterface wrapped)
{
mWrapped = wrapped;
}
public DoStuff(object param)
{
var result = mWrapped.DoStuff(param);
// snip
return result;
}
}
Now the argument I need for Implementation constructor I get from user in run-time.
IMyInterface GetMyObject()
{
string arg = AskUserForString();
return mContext.Resolve // HOW?
}
So what is the proper way to set this up and resolve to Decorated instance?
The example is simple. But imagine there are more layers (decorators/adapters) and the innermost implementation needs parameter I get in run-time.
I am assuming you are using autofac, as it is in the tags of the question.
You can try something along these lines:
public class ImplementationFactory
{
private readonly IComponentContext container;
public ImplementationFactory(IComponentContext container)
{
this.container = container;
}
public IMyInterface GetImplementation(string arg)
{
return container.Resolve<IMyInterface>(new NamedParameter("arg", arg));
}
}
And the registration/resolving part:
var builder = new ContainerBuilder();
builder.RegisterType<ImplementationFactory>();
builder.RegisterType<Implementation>().Named<IMyInterface>("implementation");
builder.Register((c, args) => new Decorator(c.ResolveNamed<IMyInterface>("implementation", args.First())))
.As<IMyInterface>();
var container = builder.Build();
var factory = container.Resolve<ImplementationFactory>();
var impl = factory.GetImplementation("abc"); //returns the decorator
If you have multiple decorators, you can chain them in the order you want within the registration:
builder.Register((c, args) => new Decorator(c.ResolveNamed<IMyInterface>("implementation", args.First())));
builder.Register((c, args) => new SecondDecorator(c.Resolve<Decorator>(args.First()))).As<IMyInterface>();
Here is a good article about decorator support in autofac as well.
You could create a factory object for the implementation and each of your decorators, and have the decorators' factories act like decorators to the implementation factory and just pass the input into the resolve call. Those you'd probably setup at application startup or in some configuration file.
To be very flexible, I would make a factory that takes a
Func<IMyInterface, IMyInterface>
or even a
Func<IMyInterface, string, IMyInterface>)
so it could build any kind of IMyInterface implmentation you want.
So something like this
interface IMyInterfaceFactory
{
IMyInterface Resolve(string parameter);
}
class DecoratorFactory : IMyInterfaceFactory
{
IMyInterfaceFactory parent;
Func<IMyInterface, string, IMyInterface> resolver;
public DecoratorFactory(
IMyInterfaceFactory parent,
Func<IMyInterface, string, IMyInterface> resolver)
{
this.parent = parent;
this.resolver= resolver;
}
public IMyInterface Resolve(string parameter)
{
var decoratee = parent.Resolve(parameter);
return resolver(decoratee, parameter);
}
}
And if you need more complex operations in the Resolve method, such as picking between multiple parents or resolver delegates, then you could just make another implementation of the factory interface for those.
Whats wrong with just handing over the param to the interface.DoStuff method. Since the argument seems to be mandatory and is not a qualifier for a specific implementation of the interface you can just add another parameter to the DoStuff method.

Ninject. Optional Injection

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

Categories