Registering same concrete class with RegisterAutoWired and RegisterAutoWiredAs - dependency-injection

My question is quite simple. I have to register all implementations by their interface and concrete types.
container.RegisterAutoWiredAs<AuthenticationManager, IAuthenticationManager>();
container.RegisterAutoWired<AuthenticationManager>();
I am using default singleton lifecycle. I want to make sure they resolve to same instance but my test shows I end up with two instances.
if (!ReferenceEquals(container.Resolve<IAuthenticationManager>(),
container.Resolve<AuthenticationManager>()))
{
throw new ApplicationException("multiple instances");
}
Is there way to use a single instance here?

Registering it twice causes a new instance for each type to be created, one for the interface and once for the concrete type.
If you want the same singleton instance you would first register an autowired instance and then just register against the other type resolving the same instance, e.g:
container.RegisterAutoWiredAs<AuthenticationManager, IAuthenticationManager>();
and either
container.Register(c => (AuthenticationManager)c.Resolve<IAuthenticationManager>());
or
var instance = (AuthenticationManager)container.Resolve<IAuthenticationManager>();
container.Register(instance);

Related

Specifying which concrete type to retrieve

I am looking at structuremap as an IOC/DI tool. Looking at this example:
http://docs.structuremap.net/QuickStart.htm
The only thing that does not make sense is, if I have an interface and derive several concrete types from it, in the code:
public class ClassThatGetsAnIValidator
{
public void SaveObject(object objectToSave)
{
// Go get the proper IValidator from StructureMap
IValidator validator = ObjectFactory.GetInstance();
var notification = validator.Validate(objectToSave);
if (notification.IsValid())
{
// save the object
}
}
}
How do I know which validator I get? IE I may have an AlphaBetValidator, NumericValidator, etc, with different method bodys and so on.....
I think this is the point:
Registering "what" and "how" StructureMap should build or find those requested services (the tedious part, but it's gotten much better over the years)
Which I struggle to grasp.
Please help.
Thanks
From the documentation:
If there is only one Instance for a registered PluginType, that
Instance will be assumed to be the default for the PluginType.
Otherwise, if there is more than one Instance for a PluginType,
StructureMap must be explicitly told which Instance is the default,
otherwise the call to GetInstance() will throw an exception (202).
To resolve to a particular instance you could use the naming mechanism. From the same documentation page:
Sometimes it's advantageous to retrieve a "named" instance of a type.
Let's say that you're building a system that needs to connect to
interface with multiple external shipping systems. You've designed an
interface for your system called IShippingSystem that hides the
details of each external shipping behind adapters. The rest of your
code should only "know" how to interact with the IShippingSystem, but
at some point, some class needs to know how to select and retrieve the
proper instance of IShippingSystem. Before the advent of IoC
containers like StructureMap, you would have coded a Factory class and
possibly a Builder class by hand to do the construction. With
StructureMap, this code is simply a call to the
ObjectFactory.GetNamedInstance(Type, string) method.
IShippingService internationalService = ObjectFactory.GetNamedInstance<IShippingService>("International");
IShippingService domesticService = ObjectFactory.GetNamedInstance<IShippingService>("Domestic");

Is it possible to pass arguments to Symony2 container constructor

When creating an service container in Symfony2 you mostly pass "static" arguments (like other classes etc.) to its constructor.
However I'd like to create a factory and therefore I need to be able to pass an dynamic argument to the service constructor.
The examples I found ( e.g. http://symfony.com/doc/current/cookbook/service_container/factories.html) are all ending up using static arguments as argument.
But what do I have to do, if I want my factory to decide which object to return based on (for example) user input?
I have some problems understanding why service factory should not work on your case. Do you need to return different service class unrelated to each other?
What I see from the factory example is that you could do something like this:
class NewsletterFactory
{
public function __constructor(...)
{
// Receive arguments needed to create the service below
}
public function get()
{
// Say the variable $userInput exists and is derived from constructor
if ($userInput === 'string')
return new NewsletterManager($dynamicArgument1);
if ($userInput === 'integer')
return new AnotherNewsletterManager($dynamicArgument2);
return new DefaultNewsletterManager();
}
}
Now, if this doesn't fit your needs. You can also create a service say CustomFactory that returns what you need. What is returned is not directly a service, so you can do whatever you want. But this would prevent you from requesting the objects created by CustomFactory from the dependency container.
Similar to that is the FormFactory. It is the factory used to instantiate form type. But the FormFactory is more powerfull since it is coupled with a dependency injection tag and a compiler pass, which register each types into the dependency injection system so they can be retrieved on their own. I don't exactly all the internals of the Form component but I think it could solve your problem if other methods do not.
Regards,
Matt

Maintaining a single instance of a concrete class with unity

When using unity, if i attempt to inject a concrete type that i havent explicitly registered with the container, unity will attempt to locate the current type and will instantiate a new one for me, before injecting it into the class that depends upon it.
How can i ensure that only a single instance of this type is used? Do i need to explicitly register an instance with the container beforehand?
From MSDN:
You can use the Unity container to generate instances of any object that has a public constructor (in other words, objects that you can create using the new operator), without registering a mapping for that type with the container. When you call the Resolve method and specify the default instance of a type that is not registered, the container simply calls the constructor for that type and returns the result.
So simply put, yes, you have to register a mapping for your type to be able to use it as singleton in your app. You can achieve it using RegisterInstance method or RegisterType and providing the ContainerControlledLifetimeManager as the lifetime manager.

Openrasta: Swap instance in dependency resolver

Suppose I register some instance in OpenRasta's dependency resolver using
resolver.AddDependencyInstance(IInterface, instance, DependencyLifetime.Singleton)
Now if I want to swap that instance later, say to reread fresh data from the db, is another call to resolver.AddDependencyInstance the right thing to do?
Checking the InternalDependencyResolver implementation, it seems to be fine. However I'm asking because the behavior is not defined (in openrasta's sources, where I checked), and the method prefix "Add" is suggestive of different behavior.
I wouldn't use Singleton if you have to swap the instance at some point.
Use DependencyLifetime.Transient and have a constructor injection in the class where you need the new instance

How to set a default constructor argument to null with StructureMap?

A class has a unique constructor taking IMyInterface as its argument. If I define a concrete type of IMyInterface and registers it to StructureMap then there is no issue and my class can be instanciated with this concrete type.
However, in some cases, no concrete type will be registered. In that case, I would like to receive null for the IMyInterface parameter. Instead I get an exception:
StructureMap Exception Code: 202
No Default Instance defined for PluginFamily IMyInterface.
Is it possible to define a default value for a missing plugin?
Context: my class, which is a service, uses the Spark view engine and defines some default namespaces. The service uses a ISparkNamespacesProvider (IMyInterface) to add aditional namespaces. The client app may register such a provider or not. That's why the constructor of the service will receive either a provider or none.
Taken from here:
For<IService>().Use<MyService>()
.Ctor<IMyInterface>("nameOfParameter").Is(null);
But You should think about why Your class is dependent on IMyInterface. If it's optional - that's a code smell. Maybe You should refactor it out as method argument for method that needs it or as settable property.
There shouldn't be need for switching between concrete implementation and null. When composing dependency graph at composition root, You should know exactly what will be Your dependencies w/o .If(isSomething()).Use<MyService>().Ctor<IMyInterface>(null).
You might want to check out this tekpub presentation and this book (look for so called MEAP access) about DI and IOC.
One way to accomplish what You want is using so called 'poor man dependency injection'. That is - to define second constructor:
public MyClass():this(null){...}
But I wouldn't recommend that.
StructureMap now supports this case via UseIfNone https://structuremap.github.io/registration/fallback-services/

Resources