I am using mvc.net with StructureMap to scan and register all repositories and services for me. Now I want to register and cache by Singleton. How can I do?
IContainer container = new Container(x => {
// Register Repositories and Services
x.Scan(y => {
y.AssemblyContainingType<SomeRepository>();
y.AssemblyContainingType<SomeService>();
y.IncludeNamespaceContainingType<SomeRepository>();
y.IncludeNamespaceContainingType<SomeService>();
});
// Register Controllers
x.Scan(y => {
y.TheCallingAssembly();
y.AddAllTypesOf<IController>().NameBy(type => type.Name.Replace("Controller", ""));
});
});
Using the new API in 2.6, ITypeScanner is deprecated. This should be implemented as a convention instead. A simple example is you want to register a convention that all types of a particular interface are a singleton:
Scan(a =>
{
a.AssemblyContainingType<IMyPluginType>();
a.With(new SingletonConvention<IMyPluginType>());
a.AddAllTypesOf<IMyPluginType>();
});
Then:
internal class SingletonConvention<TPluginFamily> : IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
if (!type.IsConcrete() || !type.CanBeCreated() || !type.AllInterfaces().Contains(typeof(TPluginFamily))) return;
registry.For(typeof(TPluginFamily)).Singleton().Use(type);
}
}
You'll need to implement the ITypeScanner similar to what Jeremy Miller outlines at http://codebetter.com/blogs/jeremy.miller/archive/2009/01/20/create-your-own-auto-registration-convention-with-structuremap.aspx
So for your Controllers for instance, I would change that Scan call to be:
x.Scan(y => {
y.TheCallingAssembly();
y.With<MyNewTypeScanner>();
});
Then I would define a class elsewhere that looked something like this:
public class MyNewTypeScanner: ITypeScanner
{
//This method is responsible for determining if a type should be registered
// and then passing it to RegisterType() if so
public void Process(Type type, PluginGraph graph)
{
//At this point you would probably just test to see if type is IController
//but you can get more sophisticated without too much headache.
this.RegisterType(graph, type);
}
private void RegisterType(PluginGraph graph, Type implementingType)
{
//The argument passed to FindFamily must be the type/class that will be requested out of SM
var family = graph.FindFamily(implementingType);
family.AddType(implementingType);
family.SetScopeTo(InstanceScope.Singleton);
}
}
This should do the trick for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With