What I am trying to achieve: Have Unity load the mappings from a configuration file, then in source code resolve the types which were loaded from said configuration file
App.Config
<register type="NameSpace.ITill, ExampleTightCoupled" mapTo="NameSpace.Till, NameSpace" />
<register type="NameSpace.IAnalyticLogs, NameSpace" mapTo="NameSpace.AnalyticLogs, NameSpace" />
Code
IUnityContainer container;
container = new UnityContainer();
// Read interface->type mappings from app.config
container.LoadConfiguration();
// Resolve ILogger - this works
ILogger obj = container.Resolve<ILogger>();
// Resolve IBus - this fails
IBus = container.Resolve<IBus>();
Issue: Sometimes IBus will be defined in the App.config, and sometimes it will not be there. When I try and resolve an interface/class and it does not exist I get an exception.
Can someone educate me here?
Thanks,
Andrew
What version of Unity are you using? In v2+ there is an extension method:
public static bool IsRegistered<T>(this IUnityContainer container);
so you can do
if (container.IsRegistered<IBus>())
IBus = container.Resolve<IBus>();
An extension method would make this nicer
public static class UnityExtensions
{
public static T TryResolve<T>(this IUnityContainer container)
{
if (container.IsRegistered<T>())
return container.Resolve<T>();
return default(T);
}
}
// TryResolve returns the default type (null in this case) if the type is not configured
IBus = container.TryResolve<IBus>();
Also check out this link: Is there TryResolve in Unity?
Related
Attempting to inject data into a FluentValidation validator:
public class MyFormValidator : AbstractValidator<MyForm>
{
private readonly IQueryable<Models.User> _users;
public MyFormValidator(IQueryable<Models.User> users)
{
_users = users;
...
}
}
My validator factory:
public class DependencyResolverValidatorFactory : ValidatorFactoryBase
{
private readonly IContainer container;
public DependencyResolverValidatorFactory(IContainer container)
{
this.container = container;
}
public override IValidator CreateInstance(Type validatorType)
{
return container.ResolveOptionalKeyed<IValidator>(validatorType);
}
}
My Autofac configurator:
public class AutofacConfigurator
{
public static void Configure()
{
var builder = new ContainerBuilder();
...
builder.RegisterType<MyFormValidator>()
.Keyed<IValidator>(typeof(IValidator<MyForm>))
.As<IValidator>()
// 2nd parameter returns IQueryable<User>
.WithParameter("users", new SqlRepository<User>(dataContext))
.InstancePerRequest();
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// Register the validator factory with FluentValidation, and register
// FluentValidation as the model validator provider for the MVC framework.
// see http://www.jerriepelser.com/blog/using-fluent-validation-with-asp-net-mvc-part-3-adding-dependency-injection
var fluentValidationModelValidatorProvider =
new FluentValidationModelValidatorProvider(
new DependencyResolverValidatorFactory(container));
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
fluentValidationModelValidatorProvider.AddImplicitRequiredValidator = false;
ModelValidatorProviders.Providers.Add(fluentValidationModelValidatorProvider);
}
}
Getting the following exception:
No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
I have other validators, most of which will not need data injected into them.
This is largely new ground for me (in both Autofac and FluentValidation) and am still trying to understand what I am doing here. I suspect I'm simply registering my type incorrectly. How do I fix this and properly register my type?
(My apologies if this is too similar to other questions that were already asked.)
I have zero experience with FluentValidation, but I doubt it's the cause of your issues anyway, so I'll plow forward regardless.
The exception you're getting means that Autofac can't resolve your service as 'instance per request'. There's a lot of documentation as to what this means on the Autofac documentation page. To summarize, it means that Autofac will attempt to resolve the service from a lifetime scope that is automatically created for each request sent to the webserver. When you register something as .InstancePerRequestScope() but then attempt to resolve that service outside of that scope, you'll get the DependencyResolutionException you see.
So we've established that your MyFormValidator isn't being resolved from a 'Request' scope. Why?
The custom DependencyResolverValidatorFactory you've written takes the actual IContainer that was built by Autofac, and resolves from that. This is a special type of ILifetimeScope, the 'root scope'. There's no request lifetime scope directly associated with this, so you get your exception. You need to to resolve from an ILifetimeScope that is began from the 'request' scope, or a sub-scope that is contained within the request scope.
The Autofac/MVC integration already automatically hosts a request scope (within the AutofacDependencyResolver, see the source), but your custom DependencyResolverValidatorFactory doesn't resolve from it. If you want to do that, I suppose you could modify your DependencyResolverValidatorFactory to accept the AutofacDependencyResolver instance instead, and use that to resolve.
It would look something like this:
public class DependencyResolverValidatorFactory : ValidatorFactoryBase
{
private readonly AutofacDependencyResolver resolver;
public DependencyResolverValidatorFactory(AutofacDependencyResolver resolver)
{
this.resolver = resolver;
}
public override IValidator CreateInstance(Type validatorType)
{
return resolver.RequestLiftimeScope.ResolveOptionalKeyed<IValidator>(validatorType);
}
}
Note the RequestLifetimeScope stuck in there.
Then you create this in your .Configure() method using
var resolver = new AutofacDependencyResolver(container);
DependencyResolver.SetResolver(resolver);
var fluentValidationModelValidatorProvider =
new FluentValidationModelValidatorProvider(
new DependencyResolverValidatorFactory(resolver));
That should get rid of the exception, assuming that this factory does indeed have a request to work from when creating instances of IValidators. If not, You might need to register using the default behavior (.InstancePerDependency(), where it creates a new instance every time it's requested) or a singleton (.SingleInstance()), depending on how/if validators can or should be shared.
Good luck.
I'm trying to use MEF as ContainerAdapter in ServiceStack (https://github.com/ServiceStack/ServiceStack/wiki/The-IoC-container).
I've made ContainerAdapter:
internal class MefIocAdapter : IContainerAdapter
{
private readonly CompositionContainer _container;
internal MefIocAdapter(CompositionContainer container)
{
_container = container;
}
public T TryResolve<T>()
{
return _container.GetExportedValue<T>();
}
public T Resolve<T>()
{
return _container.GetExportedValueOrDefault<T>();
}
}
and registered it like so:
public override void Configure(Container container)
{
container.Adapter = new MefIocAdapter(_mefContainer);
}
After registering service by RegisterService(System.Type, String) function, I'm getting MEF's exception. It can't find exports:
ContractName ServiceStack.Auth.IAuthSession
RequiredTypeIdentity ServiceStack.Auth.IAuthSession
Am i misunderstood something?
Why does Funq asks adapter container to resolve internal ServiceStack's dependency?
Will funq use MEF to instantiate my services? (if not, is there something like service factory?)
P.S. When I delete container.Adapter assignment it works (but ofc my MEF dependencies are null).
When you register a Container Adapter you're telling ServiceStack to resolve all dependencies with the Adapter, it only searches ServiceStack's IOC if the dependency isn't found in your Adapter first.
The issue here is that IAuthSession is an optional property dependency where your Adapter should return null if the dependency doesn't exist so ServiceStack can then check the dependency in Funq.
In your adapter you've got it the wrong way round where Resolve<T> (used for resolving Constructor dependencies) returns the default value and TryResolve<T> throws an exception when it doesn't exist when it should return the default value. So I'd change your Adapter implementation to:
public T TryResolve<T>()
{
return _container.GetExportedValueOrDefault<T>();
}
public T Resolve<T>()
{
return _container.GetExportedValue<T>();
}
I have followed this tutorial which has worked great, until I modified my DbContext to have an additional constructor. I am now having issues with the resolution and not sure what to do to fix this. Is there an easy way to force it to grab the parameterless constructor or I am approaching this incorrectly?
DbContext with two constructors:
public class DashboardDbContext : DbContext
{
public DashboardDbContext() : base("DefaultConnection") { }
public DashboardDbContext(DbConnection dbConnection, bool owns)
: base(dbConnection, owns) { }
}
SiteController constructor:
private readonly IDashboardRepository _repo;
public SiteController(IDashboardRepository repo)
{
_repo = repo;
}
Repository:
DashboardDbContext _context;
public DashboardRepository(DashboardDbContext context)
{
_context = context;
}
UnityResolver code:
public class UnityResolver : IDependencyResolver
{
private readonly IUnityContainer _container;
public UnityResolver(IUnityContainer container)
{
_container = container;
}
public object GetService(Type serviceType)
{
try
{
return _container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = _container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
_container.Dispose();
}
}
WebApiConfig:
var container = new UnityContainer();
container.RegisterType<IDashboardRepository, DashboardRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);
Error from WebApi Call:
System.InvalidOperationException: An error occurred when trying to create a controller of type 'SiteController'. Make sure that the controller has a parameterless public constructor.
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()
InnerException: System.ArgumentException: Type 'Dashboard.Web.Controllers.SiteController' does not have a default constructor.
at System.Linq.Expressions.Expression.New(Type type)
at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
The tutorial was great and has been working well for me up until I added the second constructor.
What's happening is that you're bitten by this problem. Basically, what happened is that you didn't register your controllers explicitly in your container. Unity tries to resolve unregistered concrete types for you, but because it can't resolve it (caused by an error in your configuration), it return null. It is forced to return null, because Web API forces it to do so due to the IDependencyResolver contract. Since Unity returns null, Web API will try to create the controller itself, but since it doesn't have a default constructor it will throw the "Make sure that the controller has a parameterless public constructor" exception. This exception message is misleading and doesn't explain the real cause.
You would have seen a much clearer exception message if you registered your controllers explicitly, and that's why you should always register all root types explicitly.
But of course, the configuration error comes from you adding the second constructor to your DbContext. Unity always tries to pick the constructor with the most arguments, but it has no idea how to resolve this particular constructor.
So the real cause is that you are trying to use Unity's auto-wiring capabilities to create the DbContext. DbContext is a special type that shouldn't be auto-wired. It is a framework type and you should therefore fallback to registering it using a factory delegate:
container.Register<DashboardDbContext>(
new InjectionFactory(c => new DashboardDbContext()));
In my case, it was because of exception inside the constructor of my injected dependency (in your example - inside DashboardRepository constructor). The exception was caught somewhere inside MVC infrastructure. I found this after I added logs in relevant places.
I had the same issue and I resolved it by making changes in the UnityConfig.cs file In order to resolve the dependency issue in the UnityConfig.cs file you have to add:
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<ITestService, TestService>();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
I had the same problem. I googled it for two days. At last I accidentally noticed that the problem was access modifier of the constructor of the Controller.
I didn’t put the public key word behind the Controller’s constructor.
public class MyController : ApiController
{
private readonly IMyClass _myClass;
public MyController(IMyClass myClass)
{
_myClass = myClass;
}
}
I add this experience as another answer maybe someone else made a similar mistake.
Sometimes because you are resolving your interface in ContainerBootstraper.cs it's very difficult to catch the error. In my case there was an error in resolving the implementation of the interface I've injected to the api controller. I couldn't find the error because I have resolve the interface in my bootstraperContainer like this:
container.RegisterType<IInterfaceApi, MyInterfaceImplementaionHelper>(new ContainerControlledLifetimeManager());
then I've adde the following line in my bootstrap container : container.RegisterType<MyController>();
so when I compile the project , compiler complained and stopped in above line and showed the error.
If you are using UnityConfig.cs to resister your type's mappings like below.
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IProductRepository, ProductRepository>();
}
You have to let the know **webApiConfig.cs** about Container
config.DependencyResolver = new Unity.AspNet.WebApi.UnityDependencyResolver(UnityConfig.Container);
I really, really hope this answer helps someone else from wasting a day and a half of messing around with; Ninject, MVC design pattern, Global.asax, Web Common files etc etc.
The error itself was completely misleading in my case.
My entire application was working sound with the exception of when I called one particualr controller lets call TestController.
Test controller was using Ninject to inject an interface lets call ITest like so -
public class TestController : ApiController
{
private readonly ITest _test;
public TestController (ITest test)
{
_test= test;
}
I was making a simple GET request to one of the methods in TestController and was getting the aforementioned error for this threads question.
I eventually boiled it down to the error only occuring when ITest was injected as a parameter (as I tested a different interface and it worked soundly!)
This led me to check the Test class and realsied that I had injected an instance of itself into it! Like so -
public class Test: ITest
{
private readonly ITest_test;
public Test(ITest test)
{
_test = test;
}
Thus resulting in the entire call falling over as an unhandled exception and returning a completely bizarre error that didn't help me at all!
If you have an interface in your controller
public myController(IXInterface Xinstance){}
You must register them to Dependency Injection container.
container.Bind<IXInterface>().To<XClass>().InRequestScope();
I've got this error when I accidentally defined a property as a specific object type, instead of the interface type I have defined in UnityContainer.
For example:
Defining UnityContainer:
var container = new UnityContainer();
container.RegisterInstance(typeof(IDashboardRepository), DashboardRepository);
config.DependencyResolver = new UnityResolver(container);
SiteController (the wrong way - notice repo type):
private readonly DashboardRepository _repo;
public SiteController(DashboardRepository repo)
{
_repo = repo;
}
SiteController (the right way):
private readonly IDashboardRepository _repo;
public SiteController(IDashboardRepository repo)
{
_repo = repo;
}
In my case, Unity turned out to be a red herring. My problem was a result of different projects targeting different versions of .NET. Unity was set up right and everything was registered with the container correctly. Everything compiled fine. But the type was in a class library, and the class library was set to target .NET Framework 4.0. The WebApi project using Unity was set to target .NET Framework 4.5. Changing the class library to also target 4.5 fixed the problem for me.
I discovered this by commenting out the DI constructor and adding default constructor. I commented out the controller methods and had them throw NotImplementedException. I confirmed that I could reach the controller, and seeing my NotImplementedException told me it was instantiating the controller fine. Next, in the default constructor, I manually instantiated the dependency chain instead of relying on Unity. It still compiled, but when I ran it the error message came back. This confirmed for me that I still got the error even when Unity was out of the picture. Finally, I started at the bottom of the chain and worked my way up, commenting out one line at a time and retesting until I no longer got the error message. This pointed me in the direction of the offending class, and from there I figured out that it was isolated to a single assembly.
Install Nuget Package Unit.WebAP instead of Unity.MVC5 Make sure the correct unity package is installed using nuget
I Installed Unity.MVC5 and was facing similar exception "parameterless constructor"
public static void RegisterComponents()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
container.RegisterType<ICar, Tesla>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
In my bootstrapper:
namespace Conduit.Mam.ClientServices.Common.Initizliaer
{
public static class Initializer
{
private static bool isInitialize;
private static readonly object LockObj = new object();
private static IUnityContainer defaultContainer = new UnityContainer();
static Initializer()
{
Initialize();
}
public static void Initialize()
{
if (isInitialize)
return;
lock (LockObj)
{
IUnityContainer container = defaultContainer;
//registering Unity for MVC
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
//registering Unity for web API
// GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
#region managers
container.RegisterType<ISettingsManager, SettingsManager>();
container.RegisterType<IMamDataManager, MamDataManager>();
container.RegisterType<IAppsDataManager, AppsDataManager>();
#endregion
if (!isInitialize)
{
isInitialize = true;
}
}
}
}
}
in my controller's code:
ISettingsManager sm = mUnityContainer.Resolve<ISettingsManager>();
hovering on mUnityContainer I see ISettingsManager is mapped to SettingsManager
but then I get the error:
Exception is: InvalidOperationException - The current type, is an
interface and cannot be constructed. Are you missing a type mapping?
I have also tried
ISettingsManager sm = (ISettingsManager)mUnityContainer.Resolve<>(typeof(ISettingsManager));
but no use
Just for others (like me) who might have faced the above error. The solution in simple terms.
You might have missed to register your Interface and class (which implements that inteface) registration in your code.
e.g if the error is
"The current type, xyznamespace. Imyinterfacename, is an interface and cannot be constructed. Are you missing a type mapping?"
Then you must register the class which implements the Imyinterfacename in the UnityConfig class in the Register method. using code like below
container.RegisterType<Imyinterfacename, myinterfaceimplclassname>();
You are incorrectly using Dependency Injection. The proper way is to have your controllers take the dependencies they need and leave to the dependency injection framework inject the concrete instances:
public class HomeController: Controller
{
private readonly ISettingsManager settingsManager;
public HomeController(ISettingsManager settingsManager)
{
this.settingsManager = settingsManager;
}
public ActionResult Index()
{
// you could use the this.settingsManager here
}
}
As you can see in this example the controller doesn't know anything about the container. And that's how it should be.
All the DI wiring should happen in your Bootstraper. You should never use container.Resolve<> calls in your code.
As far as your error is concerned, probably the mUnityContainer you are using inside your controller is not the same instance as the one constructed in your Bootstraper. But since you shouldn't be using any container code in your controllers, this shouldn't be a problem anymore.
In my case, I was getting this error despite registering an existing instance for the interface in question.
Turned out, it was because I was using Unity in WebForms by way of the Unity.WebForms Nuget package, and I had specified a Hierarchical Lifetime manager for the dependency I was providing an instance for, yet a Transient lifetime manager for a subsequent type that depended on the previous type - not usually an issue - but with Unity.WebForms, the lifetime managers work a little differently... your injected types seem to require a Hierarchical lifetime manager, but a new container is still created for every web request (because of the architecture of web forms I guess) as explained excellently in this post.
Anyway, I resolved it by simply not specifying a lifetime manager for the types/instances when registering them.
i.e.
container.RegisterInstance<IMapper>(MappingConfig.GetMapper(), new HierarchicalLifetimeManager());
container.RegisterType<IUserContext, UserContext>(new TransientLifetimeManager());
becomes
container.RegisterInstance<IMapper>(MappingConfig.GetMapper());
container.RegisterType<IUserContext, UserContext>();
So that IMapper can be resolved successfully here:
public class UserContext : BaseContext, IUserContext
{
public UserContext(IMapper _mapper) : base(_mapper)
{
}
...
}
In my case, I have used 2 different context with Unitofwork and Ioc container so i see this problem insistanting while service layer try to make inject second repository to DI. The reason is that exist module has containing other module instance and container supposed to gettng a call from not constractured new repository.. i write here for whome in my shooes
May be You are not registering the Controllers.
Try below code:
Step 1.
Write your own controller factory class
ControllerFactory :DefaultControllerFactory by implementing defaultcontrollerfactory
in models folder
public class ControllerFactory :DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
try
{
if (controllerType == null)
throw new ArgumentNullException("controllerType");
if (!typeof(IController).IsAssignableFrom(controllerType))
throw new ArgumentException(string.Format(
"Type requested is not a controller: {0}",
controllerType.Name),
"controllerType");
return MvcUnityContainer.Container.Resolve(controllerType) as IController;
}
catch
{
return null;
}
}
public static class MvcUnityContainer
{
public static UnityContainer Container { get; set; }
}
}
Step 2:Regigster it in BootStrap:
inBuildUnityContainer method
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
//RegisterTypes(container);
container = new UnityContainer();
container.RegisterType<IProductRepository, ProductRepository>();
MvcUnityContainer.Container = container;
return container;
}
Step 3:
In Global Asax.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
Bootstrapper.Initialise();
ControllerBuilder.Current.SetControllerFactory(typeof(ControllerFactory));
}
And you are done
I had this problem, and the cause was that I had not added the Microsoft.Owin.Host.SystemWeb NuGet package to my project. Although the code in my startup class was correct, it was not being executed.
So if you're trying to solve this problem, put a breakpoint in the code where you do the Unity registrations. If you don't hit it, your dependency injection isn't going to work.
Below code will be helpful for you
public static IUnityContainer Initialise(IUnityContainer container = null)
{
if (container == null)
{
container = new UnityContainer();
}
container.RegisterType<ISettingsManager, SettingsManager>();
container.Resolve<SettingsManager>();
container.RegisterType<SettingsManagerController>(new InjectionProperty("_SettingManagerProvider", new ResolvedParameter<ISettingManager>()));
return container;
}
I am trying to use Castle Windsor with MS Test. The test class only seems to use the default constructor. How do I configure Castle to resolve the service in the constructor?
Here is the Test Class' constructors:
private readonly IWebBrowser _browser;
public DepressionSummaryTests()
{
}
public DepressionSummaryTests(IWebBrowser browser)
{
_browser = browser;
}
My component in the app config looks like so:
<castle>
<components>
<component id="browser"
service="ConversationSummary.IWebBrowser, ConversationSummary"
type="ConversationSummary.Browser" />
</components>
</castle>
Here is my application container:
public class ApplicationContainer : WindsorContainer
{
private static IWindsorContainer container;
static ApplicationContainer()
{
container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));
}
private static IWindsorContainer Container
{
get { return container; }
}
public static IWebBrowser Browser
{
get { return (IWebBrowser) Container.Resolve("browser"); }
}
}
MS test requires the default constructor. What am I missing?
Thanks!
Since MSTest requires the default constructor it also means that it only uses this constructor. Thus, you can never get it to use the overloaded constructor. That's not an issue with Castle Windsor, but just the way MSTest works.
It's not that big of a deal though, because you shouldn't need to use a container for unit testing anyway.
When you use Windsor, you may want to consider using the Fluent Registration API instead of XML.
Another thing is that you shouldn't use a static Service Locator - it's an anti-pattern. This means that the ApplicationContainer class is redundant and should be deleted.