StructureMap Convention - Differences between Registy.AddType and Registry.For().Use() - structuremap

Short question. Exists some diference between registry.AddType(pluginType, type); and registry.For(pluginType).Use(type); ?
Code:
public class BasicConvention : ConfigurableRegistrationConvention
{
public override void Process(Type type, Registry registry)
{
if (something)
registry.For(pluginType).Use(type).Singleton();
}
}
}
and
public class BasicConvention : ConfigurableRegistrationConvention
{
public override void Process(Type type, Registry registry)
{
if (something)
registry.AddType(pluginType, type);
}
}
}
Using WhatDoIHave() I can see the same:
Using AddType:
===============================================================================================================================================================================================================================================================================
PluginType Namespace Lifecycle Description Name
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ISession Paf.Application.Session Transient Paf.Application.Session ('Paf.Application.Session, Paf.Modules.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null') Paf.Application.Session,... (Default)
===============================================================================================================================================================================================================================================================================
Using For().Use():
===============================================================================================================================================================================================================================================================================
PluginType Namespace Lifecycle Description Name
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ISession Paf.Application.Session Singleton Paf.Application.Session (Default)
===============================================================================================================================================================================================================================================================================
The only difference is in the description ...
Somebody?

The call to registry.AddType(pluginType, type) is basically shorthand for chaining together For and Use as in registry.For(pluginType).Use(type).
Calling registry.AddType(pluginType, type) causes a direct call to Registry.alter.set with the plugin type and the concrete type specified together.
Calling registry.For(pluginType).Use(type) chains together For and Use. The call to For returns a new GenericFamilyExpression (the constructor calls Registry.alter.set for the interface type), and the call to Use ends up calling Registry.alter.set to make the concrete type the default for the plugin family.
See the source code for Registry.cs and GenericFamilyExpression.cs, and other classes in the StructureMap source.

The accepted answer is not entirely correct. They are not the same. Which is surprisingly is indicated at the end of an answer. Use will set default instance for plugin (type) and AddType will not. So you will not be able to use Structure map as service locator with AddType. You can have this error No default Instance is registered and cannot be automatically determined for type <type>

Related

Guice PrivateModule providing both named and not named injections

I have a PrivateModule defining the following configuration:
public void configure() {
Optional<String> annotationName = Optional.ofNullable(config.getString(ANNOTATION_NAME_KEY));
if (annotationName.isPresent()) {
bind(SqlClient.class).annotatedWith(named(annotationName.get()))
.toProvider(this::createClient)
.in(Singleton.class);
expose(SqlClient.class).annotatedWith(named(annotationName.get()));
} else {
bind(SqlClient.class)
.toProvider(this::createClient)
.in(Singleton.class);
expose(SqlClient.class);
}
}
#Provides
private SqlClient createClient() {
return SqlClient.init(config);
}
This private module is initialized multiple times vs json configuration, providing multiple sql clients with different configurations. This works ok when all of the configurations have ANNOTATION_NAME_KEY: calling
#Inject
#Named("AAA")
SqlClient aaaClient;
#Inject
#Named("BBB")
SqlClient bbbClient;
returns expected results. But when i have a json configuration that has no ANNOTATION_NAME_KEY key, this to provide a solution for case without named annotation like
#Inject
SqlClient defaultClient;
I get the following exception:
A binding to my.SqlClient was already configured at my.SqlClientModule.configure(SqlClientModule.java:110).
Am I missing something or the entire idea of mixing named and non-named injections are wrong? Thanks.

ASP.NET MVC + Ninject: InRequestScope

I want to create instance of PerRequestResourceProvider using ninject InRequestScope:
public class PerRequestResourceProvider: IPerRequestResourceProvider
{
priavte readonly _perRequestResorceInstance;
public PerRequestResourceProvider()
{
_perRequestResorceInstance = new PerRequestResource();
}
public PerRequestResource GetResource()
{
return _perRequestResorceInstance;
}
}
public interface IPerRequestResourceProvider
{
PerRequestResource GetResource();
}
In my NinjectDependencyResolver:
.....
kernel.Bind<IPerRequestResourceProvider>.To<PerRequestResourceProvider>().InRequestScope();
I inject IPerRequestResourceProvider in few classes. But when I add breakpoint to PerRequestResourceProvider constructor I see that PerRequestResourceProvider is created three times during one request and not single per request. What's wrong?
Update: source code ttps://bitbucket.org/maximtkachenko/ninjectinrequestscope/src
There are two issues with your code:
Ninject is not getting initialized correctly.
You need one of the Ninject.MVCx packages (according to the MVC version you are using). To configure it correctly, see: http://github.com/ninject/ninject.web.mvc
You are injecting PerRequestResourceProvider (the class type), and not IPerRequestResourceProvider (the interface type) into HomeController, thus the .InRequestScope() defined on the IPerRequestResourceProvider binding is not taking any effect. Change the HomeController constructor to get the inteface type injected and you're good.
Ninject does not require bindings for instantiatable (non-abstract,..) classes. This is why it is not obvious when the wrong binding is used.

Default values for constructor arguments in a library project

I am writing a library that will provide a collection of public types to its consumers.
I want to make types from this library dependency injection friendly. This means that every class needs to have a constructor through which it is possible to specify every single dependency of the object being initialized. I also want the library to adhere to the convention over configuration principle. This means that if a consumer wants the default behavior, he may use a parameterless constructor and the object will somehow construct the dependencies for itself.
In example (C#):
public class Samurai {
private readonly IWeapon _weapon;
// consumers will use this constructor most of the time
public Samurai() {
_weapon = ??? // get an instance of the default weapon somehow
}
// consumers will use this constructor if they want to explicitly
// configure dependencies for this instance
public Samurai(IWeapon weapon) {
_weapon = weapon;
}
}
My first solution would be to use the service locator pattern.
The code would look like this:
...
public Samurai() {
_weapon = ServiceLocator.Instance.Get<IWeapon>();
}
...
I have a problem with this, though. Service locator has been flagged as an anti-pattern (link) and I completely agree with these arguments. On the other hand, Martin Fowler advocates use of the service locator pattern exactly in this situation (library projects) (link). I want to be careful and eliminate the possible necessity to rewrite the library after it shows up that service locator really was a bad idea.
So in conclusion - do you think that service locator is fine in this scenario? Should I solve my problem in a completely different way? Any thought is welcome...
If you want to make life easier for users who are not using a DI container, you can provide default instances via a dedicated Defaults class which has methods like this:
public virtual Samurai CreateDefaultSamurai()
{
return new Samurai(CreateDefaultWeapon());
}
public virtual IWeapon CreateDefaultWeapon()
{
return new Shuriken();
}
This way you don't need to pollute the classes themselves with default constructors, and your users aren't at risk of using those default constructors unintentionally.
There is an alternative, that is injecting a specific provider, let's say a WeaponProvider in your case into your class so it can do the lookup for you:
public interface IWeaponProvider
{
IWeapon GetWeapon();
}
public class Samurai
{
private readonly IWeapon _weapon;
public Samurai(IWeaponProvider provider)
{
_weapon = provider.GetWeapon();
}
}
Now you can provide a local default provider for a weapon:
public class DefaultWeaponProvider : IWeaponProvider
{
public IWeapon GetWeapon()
{
return new Sword();
}
}
And since this is a local default (as opposed to one from a different assembly, so it's not a "bastard injection"), you can use it as part of your Samurai class as well:
public class Samurai
{
private readonly IWeapon _weapon;
public Samurai() : this(new DefaultWeaponProvider())
{
}
public Samurai(IWeaponProvider provider)
{
_weapon = provider.GetWeapon();
}
}
I have used the following approach in my C# project. The goal was to achieve dependency injection (for unit / mock testing) whilst not crippling the implementation of the code for a "normal use case" (i.e. having a large amount of new()'s that are cascaded through the execution flow).
public sealed class QueueProcessor : IQueueProcessor
{
private IVbfInventory vbfInventory;
private IVbfRetryList vbfRetryList;
public QueueProcessor(IVbfInventory vbfInventory = null, IVbfRetryList vbfRetryList = null)
{
this.vbfInventory = vbfInventory ?? new VbfInventory();
this.vbfRetryList = vbfRetryList ?? new VbfRetryList();
}
}
This allows DI but also means any consumer doesn't have to worry about what the "default instance flow" should be.

Unity and Object Creation

I am using unity as my IoC container. I am trying to implement a type of IProviderRepository. The concrete implementation has a constructor that accepts a type of IRepository. When I remove the constructor parameter from the concrete implementation everything works fine. I am sure the container is wired correctly. When I try to create the concrete object with the constructor I receive the following error:
"The current build operation (build key Build Key[EMRGen.Infrastructure.Data.IRepository1[EMRGen.Model.Provider.Provider], null]) failed: The current type, EMRGen.Infrastructure.Data.IRepository1[EMRGen.Model.Provider.Provider], is an interface and cannot be constructed. Are you missing a type mapping? (Strategy type BuildPlanStrategy, index 3)".
Is it possible to achieve the above mention functionality with Unity? Namely have Unity infer a concrete type from the Interface and also inject the constructor of the concrete type with the appropriate concrete object based on constructor parameters. Below is sample of my types defined in Unity and a skeleton class listing for what I want to achieve. IProviderRepository is implemented by ProviderRepository which has a constructor that expects a type of IRepository.
<typeAlias alias="ProviderRepositoryInterface" type="EMRGen.Model.Provider.IProviderRepository, EMRGen.Model" />
<typeAlias alias="ProviderRepositoryConcrete" type="EMRGen.Infrastructure.Repositories.Providers.ProviderRepository, EMRGen.Infrastructure.Repositories" />
<typeAlias alias="ProviderGenericRepositoryInterface" type="EMRGen.Infrastructure.Data.IRepository`1[[EMRGen.Model.Provider.IProvider, EMRGen.Model]], EMRGen.Infrastructure" />
<typeAlias alias="ProviderGenericRepositoryConcrete" type="EMRGen.Infrastructure.Repositories.EntityFramework.ApplicationRepository`1[[EMRGen.Model.Provider.Provider, EMRGen.Model]], EMRGen.Infrastructure.Repositories" />
<!-- Provider Mapping-->
<typeAlias alias="ProviderInterface" type="EMRGen.Model.Provider.IProvider, EMRGen.Model" />
<typeAlias alias="ProviderConcrete" type="EMRGen.Model.Provider.Doctor, EMRGen.Model" />
Illustrate the call being made inside my class:
public class PrescriptionService
{
PrescriptionService()
{
IUnityContainer uc = UnitySingleton.Instance.Container;
UnityServiceLocator unityServiceLocator = new UnityServiceLocator(uc);
ServiceLocator.SetLocatorProvider(() => unityServiceLocator);
IProviderRepository pRepository =
ServiceLocator.Current.GetInstance<IProviderRepository>();
}
}
public class GenericRepository<IProvider> : IRepository<IProvider>
{
}
public class ProviderRepository : IProviderRepository
{
private IRepository<IProvider> _genericProviderRepository;
//Explict public default constructor
public ProviderRepository(IRepository<IProvider> genericProviderRepository)
{
_genericProviderRepository = genericProviderRepository;
}
}
What you want to do is possible, but you need to tell Unity how to map from interfaces to concrete types. AFAICT, your current configuration registers a lot of types, but doesn't specify how they relate to each other.
That said, static Service Locator is an anti-pattern. Consider changing your code to use proper Constructor Injection instead. That would also simplify your code considerably:
public class PrescriptionService
{
private readonly IProviderRepository pRepository;
public PrescriptionService(IProviderRepository pRepository)
{
if (pRepository == null)
{
throw new ArgumentNullException("pRepository");
}
this.pRepository = pRepository;
}
}
Using Unity, you would be able to wire it up like this:
var container = new UnityContainer();
container.RegisterType<PrescriptionService>();
container.RegisterType<IProviderRepository, ProviderRepository>();
container.RegisterType<IRepository<IProvider>, MyRepository<IProvider>>();
var ps = container.Resolve<PrescriptionService>();
Configure the container and resolve all components in the application's Composition Root.
You should only use XML configuration if you need to be able to change certain components without recompiling your application.

Structure Map Generic Type Scanner

High Level
With StructureMap, Can I define a assembly scan rule that for an interface IRequestService<T> will return the object named TRequestService
Examples:
FooRequestService is injected when IRequestService<FooRequest> is requested
BarRequestService is injected when IRequestService<BarRequest> is requested
Details
I have a generic interface defined
public interface IRequestService<T> where T : Request
{
Response TransformRequest(T request, User current);
}
and then I have multiple Request objects that implement this interface
public class FooRequestService : IRequestService<Foo>
{
public Response TransformRequest(Foo request, User current) { ... }
}
public class BarRequestService : IRequestService<Bar>
{
public Response TransformRequest(Bar request, User current) { ... }
}
Now I am at the point where I need to register these classes so that StructureMap knows how to create them because in my controller I want have the following ctor (which I want StructureMap to inject a FooRequestService into)
public MyController(IRequestService<Foo> fooRequestService) { ... }
Right now to get around my issue I have implemented an empty interface and instead of having the FooRequestService implement the generic interface I have it implement this empty interface
public interface IFooRequestService : IRequestService<Foo> { }
Then my controllers ctor looks like so, which works with StructureMaps' Default Convention Scanner
public MyController(IFooRequestService fooRequestService) { ... }
How could I create a rule with StructureMap's assembly scanner to register all objects named TRequestService with IRequestService<T> (where T = "Foo", "Bar", etc) so that I don't have to create these empty Interface definitions?
To throw something else into the mix, where I am handling StructureMap's assembly scanning does not have any reference to the assembly that defines IRequestService<T> so this has to use some sort of reflection when doing this. I scanned the answer to "StructureMap Auto registration for generic types using Scan" but it seems as though that answer requires a reference to the assembly that contains the interface definition.
I am on the path of trying to write a custom StructureMap.Graph.ITypeScanner but I am kind of stuck on what to do there (mainly because I have little experience with reflection).
You are on the right path with the scanner. Thankfully there is one built into StructureMap. Unfortunately it is not yet, as of this writing, released. Get the latest from trunk and you will see a few new things available within the scanner configuration. An example for your needs is below.
public class MyRegistry : Registry
{
public MyRegistry()
{
Scan(x =>
{
x.TheCallingAssembly();
//x.AssembliesFromApplicationBaseDirectory();
x.WithDefaultConventions();
x.ConnectImplementationsToTypesClosing(typeof (IRequestService<>));
});
}
}
First you need to tell the scanner configuration which assemblies to include in the scan. The commented AssembliesFromApplicationBaseDirectory() method also might help if you are not doing a registry per assembly.
To get your generic types into the container use ConnectImplementationsToTypesClosing.
For an example on how to setup use registries when setting up the container see:
http://structuremap.sourceforge.net/ConfiguringStructureMap.htm
If you like you can skip using registries in general and just do a scan within ObjectFactory.Initialize.
Hope this helps.

Resources