Implementing FluentSecurity over Ninject (aka porting StructureMap to Ninject) - inversion-of-control

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:
I know that code (a) will be included on Global.asax. But what is Ninject's alternative to ObjectFactory.GetAllInstances()?
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.

Marius Schulz has written an excellent article that should help anyone wanting to use Ninject together with FluentSecurity.
Setting Up FluentSecurity to Use Ninject for Dependency Resolution

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

I had same problem like you had with Ninject. After hours of googling I downloaded the source code from github. I understood the code and debugged few methods to figured out how to resolve the services. All I have to do is provide a service locator to find the PolicyViolationException handlers.
Ninject equivalent seems to be like this.
configuration.ResolveServicesUsing(type => System.Web.Mvc.DependencyResolver.Current.GetServices(type));
I used Ninject MVC3 and I used below code to load the modules from my current MVC web project plus other assemblies.
private static void RegisterServices(IKernel kernel)
{
kernel.Load("*.dll");
//kernel.Load(Assembly.GetExecutingAssembly());
}
I configured PolicyViolationException handlers in my module:
public class MainWebNinjectModule : NinjectModule
{
public override void Load()
{
// other bindings here
Bind<IPolicyViolationHandler>().To<DenyAnonymousAccessPolicyViolationHandler>();
}
}
Other required dependencies like ISecurityHandler, ISecurityContext etc are resolved by the internal IoC used in FluentSecurity.

Related

Castle Windsor Lifestyle configuration

I've spent some time looking around, and there doesn't seem to be an obvious solution to this scenario.
I register all types from an assembly (that's about 80 types, interfaces are in separate assembly)
public static void RegisterAllFromAssemblies(string a)
{
IoC.Container.Register(
AllTypes.FromAssemblyNamed(a)
.Pick()
.WithService.FirstInterface()
.Configure(o => o.LifeStyle.PerWebRequest)
);
}
now say if i want to use a different LifeStyle for one of those objects, i can't override since i'll get the There is a component already registered for the given key error.
i've looked into various ways to modify the lifestyle after this registration, but so far haven't been able to make anything work.
what should be the ideal solution here? i'd prefer not to give up the AllTypes functionality.
i suppose i could specify a .Where filter when registering all and skip a few objects to be registered manually, but that's not a very enterprisey solution..
I believe you're talking about registering all of the types in an assembly where some of the types in the assembly might need to be registered with different lifestyles. So you've got IRepository which needs to be a PerWebRequest and ITypeMapper which can be a singleton.
I clarify because you could also mean that you want to have IRepository be a PerWebRequest at one spot in your code and a singleton in another spot. Without creating crazy lifestyles, you can create your component and register it for the default lifestyle. If you need another lifestyle sometimes you can create a new component and inherit from the existing one just for use in registration (the code sample shows this if this is confusing).
I wrote the sample so that it will work for either scenario and I gave a couple different approaches all focusing around the filtering abilities of configuring multiple items at once.
For this one, I'm calling out configuration for a particular component by type. It's not as "enerprisey" as you put it, but the intent is clearer if you only have a few exceptions to the rule. You'll note you can chain together configures. The unless is required because the second configure will pick up the component for the first configure being that my only condition is the services are based on IService. This assumes that castle processes the configures in order. I believe the assumption is sound, but haven't looked at the source for awhile.
container.Register(
Classes.FromThisAssembly()
.BasedOn<IService>()
.ConfigureFor<MyComponentAsSingleton>(component => component.LifestyleSingleton())
.Configure(component => component.LifestylePerWebRequest()).Unless(type => container.Kernel.GetAssignableHandlers(type).Count() > 0));
This one uses attributes to more generically deviate from the normal lifestyle "PerWebRequest
container2.Register(
Classes.FromThisAssembly()
.BasedOn<IService>()
.ConfigureIf(
//condition to check - do we have our custom Attribute?
registration => registration.Implementation.GetCustomAttributes(false).Any(attr => typeof(ShouldBeSingleton).IsAssignableFrom(attr.GetType())),
//if true register as singleton
component => component.LifestyleSingleton(),
//else register as per web request
component => component.LifestylePerWebRequest()
));
Now that I've given you a few samples that solve your immediate issue (as I understand it) let me give you my advice for free!
First I don't really like WithService.FirstInterface(). As the intelisense states it's non-deterministic when you implement multiple interfaces. Any dev could come in and make a harmless interface change to a class and then break the system. If you can get away with WithService.DefaultInterfaces() you'd have a harder to mess up solution. Default interfaces is just telling castle that when registering the Foo component, use the service IFoo if it implements an interface named IFoo.
Second, I believe if you partition your registration logic into cohesive units you probably wouldn't have run into this problem. The key is to have many installer files that implement IWindsorInstaller. Inside of these installers you only register (using the Classes or Types to keep it enterprisey still) types that make sense for the particular installer. The chances that you have multiple lifestyle concerns in the same installer is pretty low (and if you find this, you probably need more installers)
If you followed this approach you could end up with a RepositoryInstaller, ViewInstaller, ControllerInstaller, etc. More on installers can be found on the castle documentation site
What you could do if you wanted is then have a common boostrapper for all your systems that looks into the application directory and installs all of the installers that are in the directory. Being this wasn't what you asked I'll stop elaborating, but if interested you can ping me and I can show you more about what I'm talking about.
Full sample code as a console app:
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MultipleLifecyles
{
[AttributeUsage(AttributeTargets.Class)]
public class ShouldBeSingleton : Attribute
{
}
public interface IService
{
void DoSomething();
}
public class MyComponent : IService
{
public void DoSomething()
{
throw new NotImplementedException();
}
}
[ShouldBeSingleton]
public class MyComponentAsSingleton : MyComponent
{
}
class Program
{
static void Main(string[] args)
{
//option 1
IWindsorContainer container = new WindsorContainer();
container.Register(
Classes.FromThisAssembly()
.BasedOn<IService>()
.ConfigureFor<MyComponentAsSingleton>(component => component.LifestyleSingleton())
.Configure(component => component.LifestylePerWebRequest()).Unless(type => container.Kernel.GetAssignableHandlers(type).Count() > 0));
IWindsorContainer container2 = new WindsorContainer();
container2.Register(
Classes.FromThisAssembly()
.BasedOn<IService>()
.ConfigureIf(
//condition to check - do we have our custom Attribute?
registration => registration.Implementation.GetCustomAttributes(false).Any(attr => typeof(ShouldBeSingleton).IsAssignableFrom(attr.GetType())),
//if true register as singleton
component => component.LifestyleSingleton(),
//else register as per web request
component => component.LifestylePerWebRequest()
));
Console.ReadLine();
}
}
}
Is it an option for you register manually the exceptions first? If so, components manually registered will not be re-registered by "AllTypes"(I suggest you to use Classes instead).
If you register manually a component after a "group" registration, an exception will be thrown, but not vice versa.
For example
//YourImplementation lives in assembly 'a'
IoC.Container.Register(
Component.For<YourInterface>().ImplementedBy<YourImplementation>().LifestyleSingleton()
);
IoC.Container.Register(
Classes.FromAssemblyNamed(a)
.Pick()
.WithService.FirstInterface()
.Configure(o => o.LifeStyle.PerWebRequest)
);

Registering derived repositories as immediately implemented interface

I have a situation using Repository Pattern where I would like to have some extra repositories that don't correspond to any entities.
For example here is one that does:
public class TargetRepository : RepositoryBase<Target>, ITargetRepository
{
public TargetRepository(IDatabaseFactory databaseFactory)
:base(databaseFactory)
{
}
public IEnumerable<Target> GetValidTargets(){ ... }
}
public interface ITargetRepository : IRepository<Target>
{
IEnumerable<Target> GetValidTargets();
}
Where Target is an entity.
Then I would like to have some other repositories like this:
public class ScatterPlotRepositoryProxy : TargetRepository, IScatterPlotRepositoryProxy
{
public ScatterPlotRepositoryProxy(IDatabaseFactory databaseFactory)
:base(databaseFactory)
{ }
public IEnumerable<ScatterPlotModel> GetSavedScatterPlots() {
this.GetValidTargets().Select(t => new ScatterPlotModel{ ... });
}
}
public interface IScatterPlotRepositoryProxy
{
IEnumerable<ScatterPlotModel> GetSavedScatterPlots()
}
Notice how this one inherits from TargetRepository not RepositoryBase<Entity>. That's because ScatterPlotModel is not an entity and is not even persisted. However, I'd like another layer of separation so that my TargetRespository doesn't get cluttered up with methods for all different chart types.
I haven't actually implemented this yet, so no errors yet. But I forsee my Autofac DI calls will cause problems later so I'm asking in advance.
How would I correctly register these "repository proxies" with Autofac? Currently I have this:
builder.RegisterAssemblyTypes(typeof(TargetRepository ).Assembly).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces().InstancePerApiRequest();
And adding this seems like it will conflict:
builder.RegisterAssemblyTypes(typeof(TargetRepository ).Assembly).Where(t => t.Name.EndsWith("RepositoryProxy")).AsImplementedInterfaces().InstancePerHttpRequest();
Will I get the behavior I expect (IScatterPlotRepositoryProxy will resolve to ScatterPlotRepositoryProxy and ITargetRepository should continue to resolve to TargetRepository despite ScatterPlotRepositoryProxy also implementing it from the base repository)?
Trying to do it all in one shot from the assembly to avoid having to add lines for each repository.
You're missing an abstraction in your system. This is causing you all sorts of trouble and the pain you are already witnessing.
What you need is a common abstraction over queries in the system. This removes the need to have custom repository interfaces. Custom repository interfaces such as ITargetRepository violate three out of five SOLID principles and this -without any doubt- leads to all sorts of maintainability issues.
I've written an article about this subject in the past, so I won't repeat myself here (let's keep it DRY), but you should definitely read this article: Meanwhile... on the query side of my architecture.
When applying the architectural guidance given in that article, you will have no problems registering both repositories and queries with Autofac. That will be just a matter of:
builder.RegisterAssemblyTypes(typeof(IRepository<>).Assembly)
.AsClosedTypesOf(typeof(IRepository<>));
builder.RegisterAssemblyTypes(typeof(IQueryHandler<,>).Assembly)
.AsClosedTypesOf(typeof(IQueryHandler<,>));

Dependency Injection/Property Injection on an asp.NET MVC 2 ActionFilter: Help!

I've been trying to wrap my head around the topics posted at this similar question:
Is it possible to use Dependency Injection/IoC on an ASP.NET MVC FilterAttribute?
However, I'm just not getting anywhere. Not to mention, all the solutions appear to have dependencies on other libraries which I'm not able to use (MvcContrib, Unity).
Can anyone toss together some code to explain how to make this property injection work? Or if there is another way to make this happen?
Thanks much!
Relevant code 1: Controller
namespace TxRP.Controllers
{
[GetMasterPageData]
public class BaseController : Controller
{
}
}
Relevant code 2: ActionFilter
public class GetMasterPageData : ActionFilterAttribute
{
private IEmployee emp; //<--Need to inject!
private ICache cache; //<--Need to inject!
/// <summary>
/// ActionFilter attribute which inserts the user name, access level and any error/warning messages to the MasterPage
/// Session variables which are consumed primarily by the LogOnUserControl.
/// The MasterPage will display any warning or error messages.
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//Code
}
It's not possible to use DI with attributes because they are statically compiled into your classes, so nothing can ever be injected. Some people may tell you that you can use a sort of static factory to get your dependencies, but that's not Dependency Injection - that would be Service Location - which is an anti-pattern.
However, it's possible to combine DI with action filters if you abandon the idea of attributes, but not particularly easy. You'll need to create a custom IActionInvoker, although the easiest way to do that is to derive from ControllerActionInvoker and override its GetFilters method. Here's a blog post that explains how to do that for error handling - you should be able to extrapolate from that.
When you get tired of doing that I'd advice you to switch to composing cross-cutting concerns out of Decorators and other design patterns. In that way you can implement your cross-cutting concerns independently of constraining technology.

asp.net mvc 2 with dynamically generated views

i am trying to build an asp.net mvc 2 app for data entry. I want to generate the views on the forms dynamically so will be using htmlhelpers . What would be the most flexible option for the datasource ? so when i change the database i dont have to actually change the code at all(so i guess EF is not an option)? so no model/controller changes etc. Or i don't have a choice but changing the models in my code?
Well by change database, i assume you mean change dbms, from sql server to oracle for example.
I doubt you'll find a solution to do this without any code changes at all, but you can make things a lot simpler by using interfaces for all you services.
For example
public interface IDataRepository
{
...
}
public class SqlServerDataRepository : IDataRepository
{
...
}
and for testing
public class MockRepository : IDataRepository
{
...
}
and later if you swith databases
public class OracleRepository : IDataRepository
{
...
}
This could then be used simple by referring to interfaces
public class MyService
{
public MyService(IRepository repo)
{
//ctor
{
}
And ideally injecting objects with Inversion of control, Ninject or structuremap for example.
Apologies if this is all already know to you and your looking for something different!

Library assembly IoC setup

I am working in a project that has two main parts: a class library assembly and the main application. Both are using Castle Windsor for IoC and both manually setup their list of of components in code (to aid refactoring and prevent the need for a config file). Currently the main application has code like this:
public static void Main()
{
// Perform library IoC setup
LibraryComponent.Init();
// Perform application IoC setup
IoC.Register<IXyz, Abc>("abc");
// etc, etc, ...
// Start the application code ...
}
However the call to initialise the library doesn't seem like a good solution. What is the best way to setup a class library that uses an IoC container to decouple its internal components?
Edit:
Lusid proposed using a static method on each public component in the library that would in turn make the call to initialise. One possible way to make this a bit nicer would be to use something like PostSharp to do this in an aspect-oriented way. However I was hoping for something a bit more elegant ;-)
Lusid also proposed using the AppDomain.AssemblyLoad event to perform custom steps at load time, however I am really after a way to avoid the client assembly from requiring any setup code.
Thanks!
I'm not sure if I'm understanding exactly the problem you are trying to solve, but my first guess is that you are looking for a way to decouple the need to call the Init method from your main application.
One method I've used in the past is a static constructor on a static class in the class library:
static public class LibraryComponent {
static LibraryComponent() {
Init();
}
}
If you have multiple class libraries, and would like a quick and dirty way of evaluating all of them as they are loaded, here's a (kinda hairy) way:
[STAThread]
static void Main()
{
AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(CurrentDomain_AssemblyLoad);
}
static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
IEnumerable<Type> types = args.LoadedAssembly.GetTypes()
.Where(t => typeof(IMyModuleInterface).IsAssignableFrom(t));
foreach (Type t in types)
{
doSomethingWithType(t);
}
}
The Where clause could be anything you want, of course. The code above would find any class deriving from IMyModuleInterface in each assembly that gets loaded into the current AppDomain, and then I can do something with it, whether it be registering dependencies, maintaining an internal list, whatever.
Might not be exactly what you are looking for, but hopefully it helps in some way.
You could have a registration module. Basically LibraryComponent.Init() function takes an IRegistrar to wire everything up.
The IRegistrar could basically have a function Register(Type interface, Type implementation). The implimentor would map that function back to their IOC container.
The downside is that you can't rely on anything specific to the container your using.
Castle Windsor actually has a concept called facilities that are basically just ways of wrapping standardised pieces of configuration. In this model, you would simply add the two facilities to the container and they would do the work.
Of course, this wouldn't really be better than calling a library routine to do the work unless you configured the facilities in a configuration file (consider binsor). If you are really allergic to configuration files, your current solution is probably the best.