StructureMap - Scan - Generic Interface with base implementation and specific
I have an interface something like this:
interface IGenericSetupViewModel<T>
I then have a default implemtation of this, something like this
开发者_如何学Pythonclass GenericSetupViewModel<T> : IGenericSetupViewModel<T>
For some specific classes i have a specific implementation like this:
class ContractSetupViewModel : GenericSetupViewModel<Contract>
Now i want to make StructureMap return the correct instance, when asking for a
ObjectFactory.GetInstance<GenericSetupViewModel<Contract>();
I would like to get ContractSetupViewModel returned, when asking for anything else, i would like to get an instance of
GenericSetupViewModel<T>
I tried doing this:
StructureMap.ObjectFactory.Configure(x =>
{
x.Scan(y =>
{
y.TheCallingAssembly();
y.AddAllTypesOf(typeof(IGenericSetupViewModel<>));
y.ConnectImplementationsToTypesClosing(typeof(IGenericSetupViewModel<>));
});
});
However this results in me always getting a GenericSetupViewModel and never the ContractSetupViewModel. I dont want to have to specify all specific viewmodels so is there anyway i can get this scan to work ?
There was a short-lived bug in StructureMap where ConnectImplementationToTypesClosing had trouble if your specific closing type didn't implement the interface directly. Once you get the latest version of StructureMap, the following code will work:
StructureMap.ObjectFactory.Configure(x =>
{
x.Scan(y =>
{
y.TheCallingAssembly();
y.ConnectImplementationsToTypesClosing(typeof(IGenericSetupViewModel<>));
});
x.For(typeof (IGenericSetupViewModel<>)).Use(typeof(GenericSetupViewModel<>));
});
In your GetInstance
method you should do something like:
if (AnInstance is GenericSetupViewModel)
return AnInstance as GenericSetupViewModel;
else if (AnInstance is ContractSetupViewModel)
return AnInstance as ContractSetupViewModel;
I'm not too familiar with StructureMap but could it be that you are tricked by registration priority?
Since you call y.AddAllTypesOf(typeof(IGenericSetupViewModel<>));
first, this will register the opene generic class GenericSetupViewModel<T>
first. This registration will fulfill your resolve request for GenericSetupViewModel<Contract>
and the more specific ContractSetupViewModel
registration is ignored.
That said, the Flattener sample clearly shows that having a open generic type registration and specific closed generic type registrations should work. Can you get this pattern to work with your types?
精彩评论