Ninject Interception 3.0 Interface proxy by method attributes - c#

I have just upgraded a relatively large codebase from Ninject 2.2 to Ninject 3.0. Everything seems to be going as planned except I had to make a few changes to the interception stuff that we use.
interface IFoo
{
Bar GetBar();
}
class Foo : IFoo
{
[LogMethod(Level = LogLevel.Error)]
public virtual Bar GetBar()
{
return new Bar();
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
class LogMethodAttribute : InterceptAttribute
{
public override IInterceptor CreateInterceptor(IProxyRequest request)
{
return request.Kernel.Get<ILogMethodInterceptor>();
}
public LogLevel Level { get; set; }
}
interface ILogMethodInterceptor : IInterceptor { }
class LogMethodInterceptor : ILogMethodInterceptor
{
public void Intercept(IInvocation invocation)
{
LogMethodAttribute attr = (LogMethodAttribute)invocation.Request.Method.GetCustomAttributes(typeof(LogMethodAttribute), true).FirstOrDefault();
// Log something - using attribute properties
}
}
NinjectSettings settings = new NinjectSettings { LoadExtensions = false };
IKernel kernel = new StandardKernel(settings, new DynamicProxy2Module());
kernel.Bind<ILogMethodInterceptor>().To<LogMethodInterceptor>();
kernel.Bind<IFoo>().To<Foo>();
This cut-down version is what we used to great effect with Ninject 2.3. Because interface proxies were not allowed, we had all methods marked as virtual and that enabled the Castle dynamic proxy to override them.
Now I want to move the [LogMethod] to the interface level to use interface proxies:
However, when I move it, Ninject no longer detects that I want to intercept this class.
Also if I leave it as is, a subtler problem occurs:
The invocation.Request.Method is the MethodInfo from the Interface IFoo - not the implementation Foo, this means that I cannot retrieve my attribute any more. So I am stuck between these two issues for the moment - If I put the attribute in the interface, Ninject doesn't create the proxy, if I put the attribute in the implementation, I cannot easily retrieve my attribute to access it's properties. At the moment my only solution is this:
interface IFoo
{
[LogMethod(Level = LogLevel.Error)]
Bar GetBar();
}
class Foo : IFoo
{
[LogMethod(Level = LogLevel.Error)]
public virtual Bar GetBar()
{
return new Bar();
}
}
Or use the InterfaceMapping to convert my IFoo MethodInfo to the invocation.Request.Target.GetType() (which returns the implementation type - Foo) MethodInfo.
Any recommendations?

Related

NInject: Bind Multiple Services to Single Interface

I have interface IFoo with 2 implementations Foo1 and Foo2.
public interface IFoo
{
void Process();
}
public class Foo1 : IFoo
{
public void Process()
{
}
}
public class Foo2 : IFoo
{
public void Process()
{
}
}
I'm registering them as shown below.
kernel.Bind(x => x
.FromAssemblyContaining<IFoo>()
.SelectAllClasses().InheritedFrom<IFoo>()
.BindAllInterfaces()
.Configure(b => b.InRequestScope()));
I'm trying to get all IFoo services like this
public class TestController: ApiController
{
public TestController(IFoo[] fooServices)
{
}
}
But services list fooServices is empty. I want to get all my 2 services instead.
Please help!
Issue is resolved.
The problem was the fact, that plugin libraries are loaded via custom assembly resolver AFTER registering of services. So we exposed Kernel as static property and performed registering of its services after it was loaded.
Next issue was that 'binding' could not register 2 plugins with 1 interface.
It was resolved by traversing through each plugin types and getting their interfaces and registering as follows:
foreach (var interfaceType in pluginServiceType.GetInterfaces())
kernel.bind(interfaceType).to(pluginServiceType)

Register composite pattern in StructureMap

In my project I use composite pattern and I want to register and resolve this hierarchy using StructureMap.
The code looks like this
interface IFoo
{
void Do();
}
class Foo1 : IFoo
{
public void Do()
{
Console.WriteLine("Foo1");
}
}
class Foo2 : IFoo
{
public void Do()
{
Console.WriteLine("Foo2");
}
}
class CompositeFoo : IFoo
{
private readonly IEnumerable<IFoo> foos;
public CompositeFoo(IEnumerable<IFoo> foos)
{
this.foos = foos;
}
public void Do()
{
foreach (var foo in this.foos)
{
foo.Do();
}
}
}
class Bootstrapper
{
public static void Run()
{
var container = new Container(c =>
{
c.For<IFoo>().Add<Foo1>();
c.For<IFoo>().Add<Foo2>();
c.For<IFoo>().Use<CompositeFoo>();
});
// throws exception
var result = container.GetInstance<IFoo>();
result.Do();
}
}
The specified code throws this exception
Bi-directional dependency relationship detected!
Check the StructureMap stacktrace below:
1.) Instance of IFoo (CompositeFoo)
2.) All registered children for IEnumerable<IFoo>
3.) Instance of IEnumerable<IFoo>
4.) new CompositeFoo(*Default of IEnumerable<IFoo>*)
5.) CompositeFoo
6.) Instance of IFoo (CompositeFoo)
7.) Container.GetInstance<IFoo>()
I can not find anything related to this in the official documentation or anywhere on the internet. Is this at all possible without manually specifying all possible dependencies?
The way i see it you have a couple of options:
Register CompositeFoo as CompositeFoo and not IFoo. Then ask for an instance of CompositeFoo.
cfg.For<IFoo>().Add<Foo1>();
cfg.For<IFoo>().Add<Foo2>();
cfg.ForConcreteType<CompositeFoo>();
...
var result = container.GetInstance<CompositeFoo>();
Define a new interface for the composite.
interface ICompositeFoo : IFoo {}
class CompositeFoo : ICompositeFoo
...
cfg.For<IFoo>().Add<Foo1>();
cfg.For<IFoo>().Add<Foo2>();
cfg.For<ICompositeFoo>().Use<CompositeFoo>();
...
var foo = container.GetInstance<ICompositeFoo>();
After trying to accomplish this using policies or factory classes, I sacked StructureMap in favour of Grace. There I can easily instantiate the composite object with the following code
var container = new DependencyInjectionContainer();
container.Configure(c =>
{
c.Export<Foo1>().As<IFoo>();
c.Export<Foo2>().As<IFoo>();
c.Export<CompositeFoo>().As<IFoo>();
});
var foo = container.Locate<IFoo>();
foo.Do();
And the result is as expected:
foo1
foo2
The problem with StructureMap for me is that they do not support any way to specify dependencies for an object dynamically. I could make it work if I manually write all instances which should be injected or resolve all, including the composite object. I could probably make it somehow possible using policies with injected container and specify dependencies that way, but it is too hacky in my opinion.

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

Auto-generating implementation of interface (proxy without class)

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".

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