Search code examples
inversion-of-controlninjectstructuremapfluent-security

Implementing FluentSecurity over Ninject (aka porting StructureMap to Ninject)


I'm a beginner on IoC and dependency injection. I'm reading about it, but I just can't get it. While I figure out how stuff works, I'm trying to implement some of these patterns on my project (and maybe learn by trial and error).

I'm implementing security control by using FluentSecurity package (from NuGet, btw). I need to implement a Policy Violation Handler, as described on this wiki. The problem is that the example is written for StructureMap IoC-container, and I'm using (or trying to) Ninject 2.2 (it seemed more simple for a beginner).

On their code, they suggest (a):

configuration.ResolveServicesUsing(type => ObjectFactory.GetAllInstances(type).Cast<object>());

And then (b):

public class WebRegistry : Registry
{
    public WebRegistry()
    {
        Scan(scan =>
        {
            scan.TheCallingAssembly();
            scan.AddAllTypesOf<IPolicyViolationHandler>();
        });
    }
}

My concerns:

  1. I know that code (a) will be included on Global.asax. But what is Ninject's alternative to ObjectFactory.GetAllInstances()?
  2. I have no idea neither where this code should be inserted nor what are the equivalents for WebRegistry, Scan, and the internal functions TheCallingAssembly and AddAllTypesOf.

I know this is a bit extensive question, but I appreciate any help! Thanks in advance.


Solution

  • I think this would be roughly equivelent

    //add an instance of IKernel to your MvcApplication
    [Inject]
    public IKernel Kernel { get; set; }
    ...
    configuration.ResolveServicesUsing(type => Kernel.GetAll(type));
    

    To get the ability to scan an assembly for dependencies you would need an extension for ninject called Ninject.Extensions.Conventions, which was modeled after the one from SM.

    public class WebModule : NinjectModule
    {
        public WebModule()
        {
            Kernel.Scan(a => {
                        a.FromAssemblyContaining<YourType>();
                        a.BindWithDefaultConventions();
                        a.InTransientScope();
                    });
        }
    }
    

    The assembly scanning business obviously isn't strictly necassary for what you're doing, this would work just as well. Personally I'm not a fan of assembly scanning because it seems a little too "magic", and when it doesn't work, it's not fun to debug.

    Kernel.Bind<YourType>().ToSelf();