Am I right in thinking that my QuartzJobObject can't have any DAO's or other Spring-managed objects injected into it?
Was hoping I could do something like this (orderService is what I want to inject):
<object name="checkPendingOrdersJob" type="Spring.Scheduling.Quartz.JobDetailObject, Spring.Scheduling.Quartz">
<property name="JobType" value="Munch.ScheduledTasks.CheckPendingOrdersJob" />
<!-- We can inject values through JobDataMap -->
<property name="JobDataAsMap">
<dictionary>
<!--entry key="UserName" value="Alexandre" /-->
</dictionary>
</property>
<property name="orderService" ref="orderService"/>
</object>
...which I know doesn't make sense because of the type it is. But, I could do with being able to inject some DAO's, Services etc somehow. I can't figure it out though. How can I do this?
This is what I've ended up with and it works perfectly (hopefully useful to someone else)
Job factory that is aware of Spring's context
/// <summary>
/// A custom job factory that is aware of the spring context
/// </summary>
public class ContextAwareJobFactory : AdaptableJobFactory, IApplicationContextAware
{
/// <summary>
/// The spring app context
/// </summary>
private IApplicationContext m_Context;
/// <summary>
/// Set the context
/// </summary>
public IApplicationContext ApplicationContext
{
set
{
m_Context = value;
}
}
/// <summary>
/// Overrides the default version and sets the context
/// </summary>
/// <param name="bundle"></param>
/// <returns></returns>
protected override object CreateJobInstance(TriggerFiredBundle bundle)
{
return m_Context.GetObject(bundle.JobDetail.JobType.Name, bundle.JobDetail.JobType);
}
}
The job itself (checks the DB for records and if there are at least HomeManyMenuItemsIsOK of them, everything is good). Note: menuService is an injected spring-managed object that itself has several DAO's in it). HowManyMenuItemsIsOK is a static property that's passed in through the job data map.
public class CheckMenuIsHealthyJob : QuartzJobObject
{
private static readonly ILog log = LogManager.GetLogger(typeof(CheckMenuIsHealthyJob));
public IMenuService menuService { get; set; }
public int HowManyMenuItemsIsOK { get; set; }
/// <summary>
/// Check how healthy the menu is by seeing how many menu items are stored in the database. If there
/// are more than 'HowManyMenuItemsIsOK' then we're ok.
/// </summary>
/// <param name="context"></param>
protected override void ExecuteInternal(JobExecutionContext context)
{
IList<MenuItem> items = menuService.GetAllMenuItems();
if (items != null && items.Count >= HowManyMenuItemsIsOK)
{
log.Debug("There are " + items.Count + " menu items. Menu is healthy!");
}
else
{
log.Warn("Menu needs some menu items adding!");
}
}
}
And finally the Spring config
<!-- Scheduled Services using Quartz -->
<!-- This section contains Quartz config that can be reused by all our Scheduled Tasks ---->
<!-- The Quartz scheduler factory -->
<object id="quartzSchedulerFactory" type="Spring.Scheduling.Quartz.SchedulerFactoryObject, Spring.Scheduling.Quartz">
<!-- Tell Quartz to use our custom (context-aware) job factory -->
<property name="JobFactory" ref="contextAwareJobFactory"/>
<!-- Register the triggers -->
<property name="triggers">
<list>
<ref object="frequentTrigger" />
</list>
</property>
</object>
<!-- Funky new context-aware job factory -->
<object name="contextAwareJobFactory" type="Munch.Service.ScheduledTasks.ContextAwareJobFactory" />
<!-- A trigger that fires every 10 seconds (can be reused by any jobs that want to fire every 10 seconds) -->
<object id="frequentTrigger" type="Spring.Scheduling.Quartz.CronTriggerObject, Spring.Scheduling.Quartz" lazy-init="true">
<property name="jobDetail" ref="checkMenuIsHealthyJobDetail" />
<property name="cronExpressionString" value="0/10 * * * * ?" />
</object>
<!-- Now the job-specific stuff (two object definitions per job; 1) the job and 2) the job detail) -->
<!-- Configuration for the 'check menu is healthy job' -->
<!-- 1) The job -->
<object name="checkMenuIsHealthyJob" type="Munch.Service.ScheduledTasks.CheckMenuIsHealthyJob" singleton="false">
<property name="menuService" ref="menuService"/>
</object>
<!-- 2) The job detail -->
<object name="checkMenuIsHealthyJobDetail" type="Spring.Scheduling.Quartz.JobDetailObject, Spring.Scheduling.Quartz">
<property name="JobType" value="Munch.Service.ScheduledTasks.CheckMenuIsHealthyJob"/>
<property name="JobDataAsMap">
<dictionary>
<entry key="HowManyMenuItemsIsOK" value="20" />
</dictionary>
</property>
</object>
You can do property/constructor injection into your job by overiding CreateJobInstance of
AdaptableJobFactory and register your new JobFactory instead of the default one.
The passed in TriggerFiredBundle provides you with enough infos to ask the context for a matching job (based on conventions). bundle.JobDetail.JobType.Name and bundle.JobDetail.JobType fitted my need, so back in 2008 I ended up with sth. like this (the class is derived form AdaptableJobFactory and implements IApplicationContextAware to get the context injected):
public class ContextAwareJobFactory : AdaptableJobFactory, IApplicationContextAware
{
private IApplicationContext m_Context;
public IApplicationContext ApplicationContext
{
set
{
m_Context = value;
}
}
protected override object CreateJobInstance( TriggerFiredBundle bundle )
{
return m_Context.GetObject( bundle.JobDetail.JobType.Name, bundle.JobDetail.JobType );
}
}
You need to register the ContextAwareJobFactory using the following config:
<objects xmlns="http://www.springframework.net">
<!-- Some simple dependency -->
<object name="SomeDependency" type="Namespace.SomeDependency, Assembly" />
<!-- The scheduled job, gets the dependency. -->
<object name="ExampleJob" type="Namespace.ExampleJob, Assembly" singleton="false">
<constructor-arg name="dependency" ref="SomeDependency"/>
</object>
<!-- The JobDetail is configured as usual. -->
<object name="ExampleJobDetail" type="Spring.Scheduling.Quartz.JobDetailObject, Spring.Scheduling.Quartz">
<property name="JobType" value="Namespace.ExampleJob, Assembly"/>
</object>
<!-- The new JobFactory. -->
<object name="ContextAwareJobFactory" type="Namespace.ContextAwareJobFactory, Assembly" />
<!-- Set the new JobFactory onto the scheduler factory. -->
<object id="quartzSchedulerFactory" type="Spring.Scheduling.Quartz.SchedulerFactoryObject, Spring.Scheduling.Quartz">
<property name="JobFactory" ref="ContextAwareJobFactory"/>
</object>
</objects>
I don't know if there is sth. ootb since this was developed in 2008 and I did not followed the integration progress made for quartz.net.
Related
I have a simple structure of classes, interfaces as follows:
public interface IMessagingClient (interface supporting service bus queue operation)
public class ServiceBusMessagingClient : IMessagingClient (real implementation)
public class MockMessagingClient : IMessagingClient (mock implementation for our unit test)
public class FailoverMessagingClient : IMessagingClient (this implementation internally uses 2 clients and switches roles b/w 2 as and when disaster in a datacenter occur)
{
private IMessagingClient PrimaryClient { get; set; }
private IMessagingClient SecondaryClient { get; set; }
}
We load unity config from web.config/app.config and use it in our product code and test code.
We want following:
For production scenario, PrimaryClient and SecondaryClient should of type ServiceBusMessagingClient
For Test scenario, PrimaryClient and SecondaryClient should of type MockMessagingClient
Our current unity config looks like:
<container name="azure">
<register type="IMessagingClient" mapTo="FailoverMessagingClient"/>
</container>
Do we have to use some interceptors to achieve this? Or by defining a ctor in FailoverMessagingClient and using ctor injection?
Some suggestions would be great!
You can do this using named registrations.
For example, given the following example set up:
namespace ConsoleApplication8
{
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
public interface IMessagingClient { }
public class ServiceBusMessagingClient : IMessagingClient { }
public class MockMessagingClient : IMessagingClient { }
public class FailoverMessagingClient : IMessagingClient
{
private readonly IMessagingClient primaryClient;
private readonly IMessagingClient secondaryClient;
public FailoverMessagingClient(IMessagingClient primaryClient, IMessagingClient secondaryClient)
{
this.primaryClient = primaryClient;
this.secondaryClient = secondaryClient;
}
}
class Program
{
static void Main(string[] args)
{
var container = new UnityContainer().LoadConfiguration();
var failOverMessagingClient = container.Resolve<IMessagingClient>("Two");
}
}
}
you can hook up the dependencies using the app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="IMessagingClient" type="ConsoleApplication8.IMessagingClient, ConsoleApplication8" />
<alias alias="ServiceBusMessagingClient" type="ConsoleApplication8.ServiceBusMessagingClient, ConsoleApplication8" />
<alias alias="MockMessagingClient" type="ConsoleApplication8.MockMessagingClient, ConsoleApplication8" />
<alias alias="FailoverMessagingClient" type="ConsoleApplication8.FailoverMessagingClient, ConsoleApplication8" />
<container>
<register type="IMessagingClient" name="One" mapTo="ServiceBusMessagingClient" />
<register type="IMessagingClient" name="Two" mapTo="FailoverMessagingClient">
<constructor>
<param name="primaryClient">
<dependency type="IMessagingClient" name="One" />
</param>
<param name="secondaryClient">
<dependency type="IMessagingClient" name="One" />
</param>
</constructor>
</register>
</container>
</unity>
</configuration>
Changing the line
<register type="IMessagingClient" name="One" mapTo="ServiceBusMessagingClient" />
to
<register type="IMessagingClient" name="One" mapTo="MockMessagingClient" />
will allow you to swap out your implementation of IMessagingClient as appropriate.
Personally, I would rather do this using the fluid syntax
var container = new UnityContainer();
container.RegisterType<IMessagingClient, ServiceBusMessagingClient>("One");
container.RegisterType<IMessagingClient, FailoverMessagingClient>("Two",
new InjectionConstructor(new ResolvedParameter<IMessagingClient>("One"), new ResolvedParameter<IMessagingClient>("One")));
var failOverMessagingClient = container.Resolve<IMessagingClient>("Two");
When using the unity container, you can override an existing registration by registering it again for a different class.
For example:
If you run this code:
container.RegisterType<IMessagingClient, ServiceBusMessagingClient>();
container.RegisterType<IMessagingClient, MockMessagingClient>();
The first registration is overridden and so IMessagingClient is mapped to MockMessagingClient. Its like the first line never executed.
You can use this fact, and in your unit test (in the arrange phase or in the setup method of your test class), simply register the IMessagingClient to the mock implementation like this (after loading the XML configuration):
container.RegisterType<IMessagingClient, MockMessagingClient>();
By the way, you might not want to use DI containers in unit tests. Take a look at this question.
I've got a working Unity container configured from code. I have to move to xml configuration, but can't make it correctly. I don't know what I am missing - maybe somebody is out there who knows the solution and can help me out!
My solution is about layering my FIX protocol library correctly, to handle different vendor specific messages differently, but to have a good robust backing API for that.
I have two interfaces:
public interface ICriteria
{
bool AreMet(Message message);
}
public interface IConsumer
{
ICriteria Criteria { get; }
void HandleMessage(Message message);
}
There is a default abstract implementation for the consumers:
namespace Fix.MessageHandling
{
public abstract class Consumer : IConsumer
{
private readonly ICriteria criteria;
protected readonly IProcessor Processor;
public ICriteria Criteria
{
get { return this.criteria; }
}
protected Consumer(IProcessor processor, ICriteria criteria)
{
//...
}
}
}
Then I've got some abstract implementations for different FIX message types: each Consumer abstraction has its own Criteria abstraction. (referenced in the constructor as well) e.g.
namespace Fix.MessageHandling.ExecutionReport
{
public abstract class Consumer : MessageHandling.Consumer
{
protected Consumer(IProcessor processor, Criteria criteria)
: base(processor, criteria)
{
// ...
}
}
public abstract class Criteria : ICriteria
{
// ...
}
}
I register the ICriteria instances from code:
container.RegisterType<ICriteria, Vendor.Criteria.Spot>("SpotCriteria");
container.RegisterType<ICriteria, Vendor.Criteria.Swap>("SwapCriteria");
// etc.
After that I register the IConsumer insatnces, which are in this case ExecutionReportConsumer instances, but I am mapping to IConsumer:
container.RegisterType<
IConsumer,
Vendor.Consumer.Spot>("SpotConsumer",
new InjectionConstructor(
container.Resolve<IProcessor>(),
container.Resolve<ICriteria>("SpotCriteria")));
// etc.
When I resolve IConsumer-s, I can get all my registered Consumers from the UnityContainer:
container.ResolveAll<IConsumer>();
This is how I tried to do this with xml after defining all the aliases:
<register type="ICriteria" mapTo="ForwardCriteria" name="ForwardCriteria" />
<register type="IConsumer" mapTo="ForwardConsumer" name="ForwardConsumer">
<constructor>
<param name="processor" dependencyType="IProcessor" />
<param name="criteria" dependencyType="ExecutionReportCriteria" dependencyName="ForwardCriteria" />
</constructor>
</register>
If I use the xml configuration and I call ResolveAll for IConsumers, I've got an exception
Resolution of the dependency failed, type = "Fix.MessageHandling.IConsumer", name = "ForwardConsumer".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type Criteria does not have an accessible constructor.
At the time of the exception, the container was:
Resolving Fix.Vendor.Consumer.Forward,ForwardConsumer (mapped from Fix.MessageHandling.IConsumer, ForwardConsumer)
Resolving parameter "criteria" of constructor Fix.Vendor.Consumer.Forward(Fix.MessageHandling.IProcessor processor, Fix.MessageHandling.ExecutionReport.Criteria criteria)
Resolving Fix.MessageHandling.ExecutionReport.Criteria,ForwardCriteria
OK, actually I figured this out by myself and I'm a newbie and don't know what to do - so I answer my own question :]
If I register the criteria interface and my concrete criteria implementations to the correct abstract base class, then it works like a charm!
<register type="ICriteria" />
<register type="ExecutionReportCriteria" mapTo="ForwardCriteria" name="ForwardCriteria" />
<register type="IConsumer" mapTo="ForwardConsumer" name="ForwardConsumer">
<constructor>
<param name="processor" dependencyType="IProcessor" />
<param name="criteria" dependencyName="ForwardCriteria" />
</constructor>
</register>
That is how I managed to get it going:
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<typeAliases>
<typeAlias alias="ICriteria"
type="Fix.MessageHandling.ICriteria, MoveUnityCode-as-configToXML" />
<typeAlias alias="ExecutionReportCriteria"
type="Fix.MessageHandling.ExecutionReport.Criteria, MoveUnityCode-as-configToXML" />
<typeAlias alias="ForwardCriteria"
type="Fix.MessageHandling.ExecutionReport.ForwardCriteria, MoveUnityCode-as-configToXML" />
<typeAlias alias="IConsumer"
type="Fix.MessageHandling.IConsumer, MoveUnityCode-as-configToXML" />
<typeAlias alias="ForwardConsumer"
type="Fix.MessageHandling.ExecutionReport.ForwardConsumer, MoveUnityCode-as-configToXML" />
<typeAlias alias="IProcessor"
type="Fix.MessageHandling.IProcessor, MoveUnityCode-as-configToXML" />
<typeAlias alias="Processor"
type="Fix.MessageHandling.Processor, MoveUnityCode-as-configToXML" />
</typeAliases>
<container>
<register type="ExecutionReportCriteria" mapTo="ForwardCriteria" name="ForwardCriteria" />
<register type="IProcessor" mapTo="Processor" />
<register type="IConsumer" mapTo="ForwardConsumer" name="ForwardConsumer">
<constructor>
<param name="processor" dependencyType="IProcessor" />
<param name="criteria" dependencyType="ExecutionReportCriteria" dependencyName="ForwardCriteria" />
</constructor>
</register>
</container>
</unity>
I'm making a simple web project using NHibernate and i'm stuck at this error whenever i try to build the sessionfactory.
The line that causes the exception is this
ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory();
People with similar problem seems to solve them by referencing Mysql.data.dll which i've already done, and checked that the dll is in my bin folder.
i suspect the fault lies in my hibernate.cfg.xml which looks like this
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">NHibernate.Dialect.MySQLDialect</property>
<property name="connection.provider">NHibernate.Driver.MySqlDataDriver</property>
<property name="connection.driver_class">NHibernate.Driver.SqlServerCeDriver</property>
<property name="connection.connection_string">connectionstring</property>
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<mapping assembly="Mcgvd" />
</session-factory>
</hibernate-configuration>
the tutorial i followed to make this project was using a helperclass to create the sessionfactory looking like this
public sealed class NHibernateHelper
{
private const string CurrentSessionKey = "nhibernate.current_session";
private static readonly ISessionFactory sessionFactory;
static NHibernateHelper()
{
sessionFactory = new Configuration().Configure().BuildSessionFactory();
}
public static ISession GetCurrentSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CurrentSessionKey] as ISession;
if (currentSession == null)
{
currentSession = sessionFactory.OpenSession();
context.Items[CurrentSessionKey] = currentSession;
}
return currentSession;
}
public static void CloseSession()
{
HttpContext context = HttpContext.Current;
ISession currentSession = context.Items[CurrentSessionKey] as ISession;
if (currentSession == null)
{
// No current session
return;
}
currentSession.Close();
context.Items.Remove(CurrentSessionKey);
}
public static void CloseSessionFactory()
{
if (sessionFactory != null)
{
sessionFactory.Close();
}
}
}
hibernate.cfg.xml and hibernate.hbm.xml are both located at the root of my project.
What am I doing wrong here ?
Your configuration is wrong.
<property name="connection.provider">NHibernate.Driver.MySqlDataDriver</property>
<property name="connection.driver_class">NHibernate.Driver.SqlServerCeDriver</property>
You've specified a driver for the connection provider, and a SQL Server CE driver when you're apparently using MySQL. Try:
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property>
besides the fault Jamie found i had to change the connection.provider property where i for some reason had put mysqldatadriver.
this is the working configuration i ended up with.
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">NHibernate.Dialect.MySQLDialect</property>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property>
<property name="connection.connection_string">connectionstring</property>
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<mapping assembly="Mcgvd" />
</session-factory>
</hibernate-configuration>
We are using spring for our IOC container in an MVC3 project. I am trying to make a base controller that will have a constructor dependency on our IUserIdentity interface. I would like to define the constructor dependency once in the application context file for the abstract class and was hoping spring would be able to inject that for each derived class.
public abstract class ControllerBase : Controller
{
private readonly IUserIdentity _userContext;
public ControllerBase(IUserIdentity userContext)
{
_userContext = userContext;
}
}
public class ChildController : ControllerBase
{
private readonly IChildDependency _childService;
public ChildController(IUserIdentity userContext, IChildDependency childService)
: base(userContext)
{
_childService= childService;
}
}
I was hoping there was a way to define something like the following - (not sure how it would work) without re-defining the UserIdentity for every derived class.
<object id="ControllerBase" abstract="true" singleton="false" >
<constructor-arg index="0">
<ref object="DefaultUserIdentity"/>
</constructor-arg>
</object>
<object id="ChildController" singleton="false" >
<constructor-arg index="1" >
<ref object="ConcreteChildDependency" />
</constructor-arg>
</object>
As expected, when I do something like this, spring does not know what to put in for the first argument in the derived (ChildController) class.
Try referring to ControllerBase object definition using the parent attribute:
<object id="ControllerBase" abstract="true" singleton="false" >
<constructor-arg index="0">
<ref object="DefaultUserIdentity"/>
</constructor-arg>
</object>
<object id="ChildController" singleton="false" parent="ControllerBase" >
<constructor-arg index="1" >
<ref object="ConcreteChildDependency" />
</constructor-arg>
</object>
This will let ChildController "inherit" the object definition from ControllerBase. See the spring.net docs for more on object definition inheritance. You might want to drop the index attributes from the constructor args, btw. They're not needed if the constructor argument types can be resolved implicitly. And your ChildController needs a type definition, of course.
I am trying to create an ASP.NET MVC application, using Spring.NET to inject dependencies. The application has three tiers: Controller, Service, and Data.
I have defined the objects in the file "~\Resources\objects.xml".
My first object, UserAccountController, requires the injecion of two Service-tier classes: UserAccountService and DepartmentService. So, the definition in objects.xml looks like this:
<object id="UserAccountController" type="App.Controllers.UserAccountController, App">
<constructor-arg index="0" ref="DepartmentService" />
<constructor-arg index="1" ref="UserAccountService" />
</object>
<object id="UserAccountService" type="App.Service.UserAccountService, App">
<property name="UserAccountDao" ref="UserAccountDao" />
</object>
<object id="UserAccountDao" type="App.Data.UserAccountDao, App" />
<object id="DepartmentService" type="App.Service.DepartmentService, App">
<property name="DepartmentDao" ref="DepartmentDao" />
</object>
<object id="DepartmentDao" type="App.Data.DepartmentDao" />
Webconfig contains this:
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
</sectionGroup>
</configSections>
<spring>
<context>
<resource uri="~/Resources/objects.xml" />
</context>
</spring>
I would prefer to use Property injection rather than constructor, but currently neither method is working.
Well, it turned out to be that ASP.NET MVC and Spring.NET just don't get along...
However, the MvcContrib package (actually, the Extras package) seems to have solved the issue. The package had a Spring Controller factory implementation that worked, and everything was happy.
(Kind of reminds me of trying to make Struts 1.X and Spring work on the Java side...)
in your bootstrapclass you have to load the spring container
ContextRegistry.getContext();
by the way you need to specify the assembly name for DepartmentDao
<object id="DepartmentDao" type="App.Data.DepartmentDao, App" />
Further information: I also have classes for SpringApplicationController and SpringControllerFactory:
SpringApplicationController.cs:
public static class SpringApplicationContext
{
private static IApplicationContext Context { get; set; }
/// <summary>
/// Returns a boolean value if the current application context contains an named object.
/// </summary>
/// <param name="objectName">Accepts the name of the object to check.</param>
public static bool Contains(string objectName)
{
SpringApplicationContext.EnsureContext();
return SpringApplicationContext.Context.ContainsObject(objectName);
}
/// <summary>
/// Return a instance of an object in the context by the specified name.
/// </summary>
/// <param name="objectName">Accepts a string object name.</param>
public static object Resolve(string objectName)
{
SpringApplicationContext.EnsureContext();
return SpringApplicationContext.Context.GetObject(objectName);
}
/// <summary>
/// Return a instance of an object in the context by the specified name and type.
/// </summary>
/// <typeparam name="T">Accepts the type of the object to resolve.</typeparam>
/// <param name="objectName">Accepts a string object name.</param>
public static T Resolve<T>(string objectName)
{
return (T)SpringApplicationContext.Resolve(objectName);
}
private static void EnsureContext()
{
if (SpringApplicationContext.Context == null)
{
SpringApplicationContext.Context = ContextRegistry.GetContext();
}
}
}
SpringControllerFactory.cs:
public class SpringControllerFactory : DefaultControllerFactory
{
public IController CreateController(RequestContext context, Type controllerType)
{
IResource input = new FileSystemResource(context.HttpContext.Request.MapPath("Resource\\objects.xml"));
IObjectFactory factory = new XmlObjectFactory(input);
return (IController) factory.GetObject(controllerType.Name);
}
public IController CreateController(RequestContext context, string controllerName)
{
IController controller = null;
string controllerClassName = string.Format("{0}Controller", controllerName);
if (SpringApplicationContext.Contains(controllerClassName))
{
controller = SpringApplicationContext.Resolve<IController>(controllerClassName);
this.RequestContext = context;
}
else
{
controller = base.CreateController(context, controllerName);
}
return controller;
}
public override void ReleaseController(IController controller)
{
IDisposable disposable = controller as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
}
I reference this in my Global.asax as follows:
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(typeof(App.Util.SpringControllerFactory));
RegisterRoutes(RouteTable.Routes);
}