Instead of allowing StructureMap to build objects directly, you can give a StructureMap Container
a Lambda function that can be called to create an object at resolution time.
Using NHibernate's ISession
as an example
of an object that typically has to be built by using an ISessionFactory
object:
public interface ISession { }
public interface ISessionFactory
{
ISession Build();
}
If we want to allow StructureMap to control the ISession
lifecycle and creation, we have to register a Lambda function as the
means of creating ISession
as shown in this example below:
public class SessionFactoryRegistry : Registry
{
// Let's not worry about how ISessionFactory is built
// in this example
public SessionFactoryRegistry(ISessionFactory factory)
{
For<ISessionFactory>().Use(factory);
// Build ISession with a lambda:
For<ISession>().Use("Build ISession from ISessionFactory", c =>
{
// To resolve ISession, I first pull out
// ISessionFactory from the IContext and use that
// to build a new ISession.
return c.GetInstance<ISessionFactory>().Build();
});
}
}
Lambda registrations can be done with any of the following four signatures:
(Expression<Func<IContext, T>> builder)
-- a simple, one line Lambda to buildT
usingIContext
(Expression<Func<T>> func)
-- a simple, one line Lambda to buildT
(string description, Func<IContext, T> builder)
-- useIContext
in your builder Lambda with a user-supplied description for diagnostics(string description, Func<T> builder)
-- Supply a complexFunc<T>
with a user-supplied description for diagnostics
Be very wary of the difference between legal Expression's
and more complicated Lambda's that will need to be Func's
. It likely doesn't matter to
you the user, but it unfortunately does to StructureMap and .Net itself. If you need to use a more complex Func
, you will have
to supply a diagnostic description.
See Working with the IContext at Build Time for more information.