Unity not using the default constructor of the class - c#

I have this class :
public class Repo
{
public Repo() : this(ConfigurationManager.AppSettings["identity"], ConfigurationManager.AppSettings["password"])
{
}
public Repo(string identity,string password)
{
//Initialize properties.
}
}
I added a line to web.config so that this type will be automatically constructed by Unity container.
but during the execution of my application, I receive this error message :
"System.InvalidOperationException : the parameter identity could not be resolved when attempting to call constructor Repo(String identity, String password) -->Microsoft.Practices.ObjectBuilder2.BuildFailedException : The current Build operation ...."
1) Why isn't Unity using the default constructor ?
2) Suppose I want Unity to use the second constructor (the parametized one), How do I
pass that information to Unity via the configuration file ?

Unity by default picks the constructor with the most parameters. You have to tell Unity to use a different one explicitly.
One way to do this is with the [InjectionConstructor] attribute like this:
using Microsoft.Practices.Unity;
public class Repo
{
[InjectionConstructor]
public Repo() : this(ConfigurationManager.AppSettings["identity"], ConfigurationManager.AppSettings["password"])
{
}
public Repo(string identity,string password)
{
//Initialize properties.
}
}
A second way of doing this, if your opposed to cluttering up classes/methods with attributes, is to specify which constructor to use when configuring your container using an InjectionConstructor:
IUnityContainer container = new UnityContainer();
container.RegisterType<Repo>(new InjectionConstructor());
From the documentation:
How Unity Resolves Target Constructors and Parameters
When a target class contains more than one constructor, Unity will use
the one that has the InjectionConstructor attribute applied. If there
is more than one constructor, and none carries the
InjectionConstructor attribute, Unity will use the constructor with
the most parameters. If there is more than one such constructor (more
than one of the "longest" with the same number of parameters), Unity
will raise an exception.

Just try to register type this way:
<register type="IRepo" mapTo="Repo">
<constructor />
</register>
Because of no param element specified in constructor element it should call default constructor.
You can also do this registration in code:
container.RegisterType<IRepo, Repo>(new InjectionConstructor());

I had a more simple problem that resulted in this error.
The container that I was using was the wrong container. I had accidentally created two different containers and my container.RegisterType<Interface,ConcreteObject> was inside of another container from the one being used.

Related

ASP Boilerplate - How does ITransient work

From what I understand, in abp, when a class implements, ITransient interface, it is automatically registered in the dependency injection system.
When I create a new project in ASPNetZero, and a class implements the ITransient, I cannot inject the said class in other projects e.g Application
Using the following snippet does not allow me to use constructor injection.
public interface ITrackAppService : ITransientDependency
public class TrackAppService : ITrackAppService
But when I register it (Even if the class does not implements ITransient), then I can use constructor injection.
IocManager.RegisterIfNot<ITrack, Track>();
Did I mistakenly understood how ITransient works?
How do I use Itransient so I can use constructor dependency injection?
Note: The class I'm trying to inject to the Application project is in a different project I created.
If you are injecting an interface to a new project, you cannot use it that way out of the box. Because your new project doesn't know your dependencies.
Each new project that uses DI must to be set as an AbpModule.
See a sample module declaration.
[DependsOn(typeof(MyBlogCoreModule))]
public class MyBlogApplicationModule : AbpModule
{
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
}
Look out the [DependsOn] attribute on the class. This helps to register the project to the DI.
So what you need to do is,
Create a new class in the new project like I showed you above.
Add the [DependsOn(typeof(YourApplicationServiceModule))] attribute to this new module.

How to register Dependencies by Names in Unity

I'm using unity to implement Dependency Injection in my .NET Web Api app.
Here is the relevent part of my WebApiCongig
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var container = new UnityContainer();
AppDependancyRegistry.Register(container);
config.DependencyResolver = new UnityResolver(container);
}
}
And here is my AppDependancyRegistry class
public static class AppDependancyRegistry
{
public static void Register(UnityContainer container)
{
container.RegisterType(typeof(IBaseRepository<>), typeof(BaseRepository<>));
//container.RegisterTypes( AllClasses.FromLoadedAssemblies(), WithMappings.FromMatchingInterface, WithName.Default);
}
}
I have mapped the Generic Repositores but I couldnt get through with registering the Manager classes to its interfaces. I dont want to map every one of Manager classes Manaually.
I have commented the part I have done from all the research. I just want a confirmation, this is how I do it as I cant get my App running now without doing some more of stuff
My manager classes:interfaces looks like
DutyManager: IDutyManager
UserDetailManager:IUserDetailManager
etc. Thanks in Advance
You will need, at some point, to register each of them. However, if you don't want to manually do each and every one of them, what you could "basically" do is, by reflection, load the assembly, iterate over every interface, check how many classes implement that interface, if there is only one, register the interface to that class as an unnamed registration.
Why unnamed? Well, named registration are useless unless you actually use the name in the registration, or in the ResolvedParameter constructor, and since you're not "hand crafting" the registrations, you wouldn't refer to them most likely.
Don't forget though that in your case, since the interface and the classes are generics, you'll need to check the ParameterType too.
I found the solution to this qn. Using Unity we can directly Map all classes to respecive Interfaces by using
container.RegisterTypes( AllClasses.FromLoadedAssemblies(), WithMappings.FromMatchingInterface, WithName.Default);
Here, Unity maps by convention where they map like this
DutyManager: IDutyManager
UserDetailManager:IUserDetailManager

Using two different databases with my model - crash on constructor

I have a project that works for a single database. Now I need to get it to work with a second (within the same project) that has the same data structure. So I am using the same model and am trying to pass in the Data Connection name upon calling my Data Context Class. Unfortunately I am receiving the following error:
The type String cannot be constructed. You must configure the
container to supply this value.
Here is the code that I tried:
public UniversityContext(string context)
: base(context){
}
When I looked for answers I found this answer for that error and it recommends, having a parameter-less constructor as well. I tried that and still the same issue.
Here it is with the parameter-less constructor:
public UniversityContext()
: base("UniversityConnection")
{
}
public UniversityContext(string context)
: base(context)
{
}
In case it matters I am using Unity.
Unity automatically tries to use the most greedy constructor. In your case this is:
public UniversityContext(string context)
You can configure this with an injection constructor, without seeing your code something like this:
container.RegisterType<UniversityContext>(
new InjectionConstructor("UniversityContext"));

How to inject arguments when using lazy types?

I have a Translation class that takes in ITranslationService as its argument. How do I inject translation service when registering the Lazy<Translation> type? This is what I've done so far, but no luck.
public class Translation
{
public Translation(ITranslationService translationService)
{
// code here
}
}
container.RegisterType<ITranslationService, TranslationService>();
container.RegisterType<Lazy<Translation>>(new InjectionConstructor(typeof(ITranslationService)));
Error message when trying to resolve Lazy<Translation> type:
The lazily-initialized type does not have a public, parameterless
constructor
First of all, Unity 3 now supports resolving Lazy<T>(See What's New section), so you don't need to do anything special, just register ITranslationService and you will be able to resolve Lazy<Translation>.
So the following only applies to Unity 2.
You can install this nuget extension from Piotr Wlodek. You will then need to enable it using:
container.AddNewExtension<LazySupportExtension>();
You will then be able to resolve Lazy<T> objects:
var lazy = container.Resolve<Lazy<Translation>>();
And the actual Translation object will not be constructed until you call lazy.Value.
If neither getting Unity3 nor that extension is an option, you could still try to manually configure Unity2 and resolve those objects.
In your case, you need to use one of the constructors in Lazy<T> that receives a Func<T> as parameter. (That is a function with no parameters that returns an instance of T, or Translation in your case).
You can use an InjectionFactory when registering Lazy<Translation> in Unity, which is a factory method that constructs a Lazy<Translation> object. The lazy object will receive in its constructor an initialization function that uses Unity to resolve the Translation:
container.RegisterType<Lazy<Translation>>(
new InjectionFactory(c => new Lazy<Translation>(() => c.Resolve<Translation>()) ));
Unity supports Lazy<T>, but you have to configure it:
unityContainer.AddNewExtension<LazySupportExtension>();
then don't do
container.RegisterType<Lazy<Translation>(new InjectionConstructor(typeof(ITranslationService)));
but instead do:
container.RegisterType<Translation>();
And use it as follows:
unityContainer.Resolve<Lazy<Translation>>();
For any one using MVC or Web API projects, just install the relevant Unity Bootstrapper Nuget package i.e Unity.AspNet.WebApi for Web API, and Unity.Mvc for MVC.
And then register your types as you normally would, either in code or through a config file. The Lazy instances will be injected automatically
private Lazy<IMapService> _mapService;
public HomeController(Lazy<IMapService> mapService)
{
//Lazy instance is injected automatically.
_mapService = mapService
}

NancyFx and TinyIoC provide single instance to module

Iv got a fairly simlpe question. Im using Nancy with a windows form (passed through the constructor (autoresolve)). If i let nancy resolve automatically every module it creates a new instance of the form, which is not what i want. I thought maybe i could register my form instance in TinyIoC and then it would always use just this instance instead of creating a new one each time. But that has proved not as simple to implement as the idea is.
Thanks in advance
you should probably do this in the bootstrapper
something like:
public class MyBootstrapper: DefaultNancyBootstrapper
{
ConfigureApplicationContainer (TinyIoCContainer container)
{
//the .AsSingleton() instructs TinyIOC to make only one of those.
container.Register<IMessageDeliverer>().AsSingleton();
base.ConfigureApplicationContainer (container);
}
}
I resolved this by not assigning the window reference to the contructor but by registering it with TinyIoC and the resolving it in the default constructor
//Registering in form
var container = TinyIoCContainer.Current;
container.Register<IMessageDeliverer>(this);
//Resolving in Module Constructor
var container = TinyIoCContainer.Current;
IMessageDeliverer mdl = container.Resolve<IMessageDeliverer>();
setDeliverer(mdl);

Categories

Resources