StructureMap and SignalR - IMessageBus, no default instance defined - c#

I used nuget to update my project to signalr 2.2 and structure map 2.6.4.
Now when my program attempts to use SignalR, structure map is throwing this error:
StructureMap.StructureMapException was unhandled by user code
HResult=-2146232832
Message=StructureMap Exception Code: 202
No Default Instance defined for
PluginFamily Microsoft.AspNet.SignalR.Messaging.IMessageBus, Microsoft.AspNet.SignalR.Core, Version=2.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
Source=StructureMap
My code hasn't change and I don't believe I'm requiring IMessageBus anywhere, so I'm not sure why structure map is now doing this. I setup a new project with a simplified structuremap 2.6.4/signalr 2.2 and never need to seed IMessageBus, so it's something about my implementation, but I'm not sure what's changed from the upgrade.
Does anyone have an idea to point me to?
Thanks!
Scott

This was solved by first looking to resolve in the base class:
public override object GetService(Type serviceType)
{
if (serviceType == null)
return null;
var service = base.GetService(serviceType);
if (service != null) return service;
return container.TryGetInstance(serviceType);
}

What solved this for me was making a change to the GetService method as well. Here is my full StrucutreMapSignalRDependencyResolver for reference:
public class StructureMapSignalRDependencyResolver : DefaultDependencyResolver
{
private readonly IContainer _container;
public StructureMapSignalRDependencyResolver(IContainer container)
{
_container = container;
}
public override object GetService(Type serviceType)
{
return _container.TryGetInstance(serviceType) ?? base.GetService(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
var objects = _container.GetAllInstances(serviceType).Cast<object>();
return objects.Concat(base.GetServices(serviceType));
}
}

Related

Error while trying to use an IoC container inside WebApi (Net Framework)

I'm trying to use an IoC container inside the WebApi template. I've created an empty Web App Framework project, and selected to use WebApi. I've then added the Unity NuGet package and added the following to Application_Start:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
UnityConfig.Register();
}
The UnityConfig:
public class UnityConfig
{
public static UnityContainer Register()
{
var container = new UnityContainer();
container.RegisterType<IMyClass, MyClass>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityResolver(container);
return container;
}
}
My UnityResolver is here (the code is largely plagiarised, but it seems pretty bog standard):
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.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()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
container.Dispose();
}
}
When I now run this, I get the following error:
Unity.Exceptions.ResolutionFailedException: 'Resolution of the
dependency failed, type =
'System.Web.Http.Hosting.IHostBufferPolicySelector', name = '(none)'.
Exception occurred while: while resolving. Exception is:
InvalidOperationException - The current type,
System.Web.Http.Hosting.IHostBufferPolicySelector, is an interface and
cannot be constructed. Are you missing a type mapping?
----------------------------------------------- At the time of the exception, the container was: Resolving
System.Web.Http.Hosting.IHostBufferPolicySelector,(none) '
Clearly, after telling it which IoC library I want to use, I need to inject some internal dependencies, or tell it to, or perhaps, register this earlier (or later).
Clearly, after telling it which IoC library I want to use, I need to inject some internal dependencies, or tell it to, or perhaps, register this earlier (or later).
That's true. You need to register all of the types that will be resolved through Unity. The error message indicates you are missing IHostBufferPolicySelector, so you need to register it.
public static UnityContainer Register()
{
var container = new UnityContainer();
// Register all types with Unity here
container.RegisterType<IHostBufferPolicySelector, OwinBufferPolicySelector>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityResolver(container);
return container;
}
I don't know for sure if OwinBufferPolicySelector is the one you need because you haven't provided enough info, but you do need to map an implementation for it (and probably several other interfaces) in order to proceed.
As noted in the comments, it would probably be easier if you install one of the premade Unity packages (such as Unity.WebAPI) to supply this implementation.
It will also help considerably if you follow the Dependency Injection in ASP.NET Web API 2 documentation.

Make sure that the controller has a parameterless public constructor error

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);
}

Using MEF with the Enterprise Library

I'm trying to override the default Unity Container behavior for the Enterprise Library so that I can use my MEF container. There are a few resources with explanations of how to do this but I'm just not getting it:
http://blogs.msdn.com/b/bobbrum/archive/2009/06/23/enterprise-library-5-0-some-architecture-changes.aspx
http://entlib.uservoice.com/forums/90505-silverlight-integration-pack/suggestions/1284693-mef-configurator-for-enterprise-library-container
http://entlib.codeplex.com/discussions/261443
There is also this post on SO but the code does not compile because LogWriter is protected. I assume this referred to an old version:
.net Mef with Enterprise Library 5.0
What I understand is that I need to use the CommonServiceLocator for my MEF container and then attach this to the Enterprise Library container. Here's what I have for my container configurator:
public class MefContainerConfigurator : IContainerConfigurator, IServiceLocator
{
[Import] private CatalogExportProvider provider;
public object GetService(Type serviceType)
{
throw new NotImplementedException();
}
public object GetInstance(Type serviceType)
{
return provider.GetExportedValue<Type>();
}
public object GetInstance(Type serviceType, string key)
{
throw new NotImplementedException();
}
public IEnumerable<object> GetAllInstances(Type serviceType)
{
throw new NotImplementedException();
}
public TService GetInstance<TService>()
{
return provider.GetExportedValue<TService>();
}
public TService GetInstance<TService>(string key)
{
return provider.GetExportedValue<TService>(key);
}
public IEnumerable<TService> GetAllInstances<TService>()
{
return provider.GetExportedValues<TService>();
}
public void RegisterAll(IConfigurationSource configurationSource, ITypeRegistrationsProvider rootProvider)
{
throw new NotImplementedException();
}
}
And in my bootstrapper:
var configurator = new MefContainerConfigurator();
// Does this line read the Enterprise Library configuration from the app.config?
IConfigurationSource cs = new SystemConfigurationSource();
EnterpriseLibraryContainer.ConfigureContainer(configurator, cs);
I think maybe I need to make use of the LogWriterImpl and ExceptionManagerImpl classes as these have constructors which accept configuration. My questions at this point would be:
How do I retrieve the configuration from the IConfigurationSource and feed it into the constructors for the LogWriterImpl and ExceptionManagerImpl constructors?
EnterpriseLibraryContainer.ConfigureContainer calls RegisterAll in my MefContainerConfigurator. Is this where I'm supposed to register all of the enterprise library types into the container?
The methods from the IServiceLocator interface that I have left as NotImplemented; I couldn't find a way to use these to return objects from my container. Am I supposed to leave them as not implemented and use the generic methods instead?
Edit
I still cannot get this totally right. Based on #Chris Tavares answer, I wrote my RegisterAll method in the MefContainerConfigurator to iterate through the TypeRegistrations and add them to a container. I cannot for the life of me figure out how to merge these to my AggregateContainer that is created in my Bootstrapper class so that I can actually use these exports outside of the ContainerConfigurator:
public void RegisterAll(IConfigurationSource configurationSource, ITypeRegistrationsProvider rootProvider)
{
var registrations = rootProvider.GetRegistrations(configurationSource);
foreach (var type in registrations)
{
var builder = new RegistrationBuilder();
builder.ForType(type.ServiceType).Export();
var cat = new AssemblyCatalog(type.ServiceType.Assembly, builder);
var container = new CompositionContainer(cat);
container.ComposeParts(this);
}
}
ConfigureAggregateCatalog in Prism bootstrapper:
protected override void ConfigureAggregateCatalog()
{
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(RegionNames).Assembly));
// Module assemblies
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(DataEntryModule).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ReportingModule).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(StatusBarModule).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(SplashScreenModule).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(WelcomeModule).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(AdministrationModule).Assembly));
AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));
}
Your container configurator is woefully incomplete. You've got one method to implement: RegisterAll, and you didn't implement it.
You don't have to read the raw configuration information from config; instead, what happens is that when you call EnterpriseLibraryContianer.ConfigureContainer, Entlib will spin through the configuration source, pick out all the important bits, and hand you a series of TypeRegistration objects. Those guys give you the type mappings, and the constructor dependencies, etc. Basically all the stuff you need to register the dependencies in your container (in this case, MEF).
So basically what you need to do is write the code that turns the abstract TypeRegistration object into the right configuration for MEF.
Unity isn't special in this regard; it has a configurator as well, and follows the exact same process, so you can look in the entlib code as an example of the kinds of things you'll need to do.
I don't know the MEF apis at all, so unfortunately cannot help you with specific implementation.

Make sure that the controller has a parameterless public constructor in Unity

I got this problem with the Controller:
An error occurred when trying to create a controller of type '*.WebMvc.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor.
Find the solution for the ApiController, but didn't find anything about normal Controller.
Created new MVC 4 project from scratch.
HomeController.cs:
public class HomeController : Controller
{
private IAccountingUow _uow;
public HomeController(IAccountingUow uow)
{
_uow = uow;
}
UnityDependencyResoler.cs:
public class UnityDependencyResolver : IDependencyResolver
{
private IUnityContainer _container;
public UnityDependencyResolver(IUnityContainer container)
{
_container = container;
RegisterTypes();
}
public object GetService(Type serviceType)
{
try
{
return _container.Resolve(serviceType);
}catch
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _container.ResolveAll(serviceType);
}catch
{
return null;
}
}
private void RegisterTypes()
{
_container.RegisterType<IAccountingUow, AccountingUow>();
}
}
Global.asax
protected void Application_Start()
{
//Omitted
DependencyResolver.SetResolver( new UnityDependencyResolver( new UnityContainer()));
}
Debugged and found out, that there are even no attempts to resolve IAccountingUow.
What i'm doing wrong?
Thinking about it whole day.
Found where is the issue. Maybe some one will face the same.
The problem is that Unity could not resolve the IAccountingUow, because of hierarchical dependancy on interfaces.
AccountingUow class has two contuctors
public AccountingUow( IRepositoryProvider repositoryProvider)
{
Init(repositoryProvider);
}
public AccountingUow()
{
Init( new RepositoryProvider(new RepositoryFactories()) );
}
Dependency Resolver is not smart enought to take the default parametless contructor. It tries to take interface dependant contructor and fails to resolve it, cause there are no rules for resolving it.
I commented out interface dependant constructor and everything worked fine.
I will post later resolver for the first contructor, maybe someone will use it.
This can also be due to an exception in the parameter-injected constructor of the outer type that is being resolved. The dependencies of that type's constructor might be getting resolved successfully, but if there is an exception in the outer constructor, Unity will report it as "Type Test.Controllers.MyControllerWithInjectedDependencies does not have a default constructor".
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"

ASP.NET MVC 3: IDepencyResolver is trying to get an implementation of IControllerFactory

Why is the IDependecyResolver trying to get an instance of IControllerFactory although I registered the DefaultControllerFactory?
Global.asax:
ControllerBuilder.Current.SetControllerFactory(typeof(DefaultControllerFactory));
DependencyResolver.SetResolver(new StructureMapDependencyResolver());
Resolver:
public class StructureMapDependencyResolver : IDependencyResolver
{
public static Func<Type, object> GetServiceViaDepencencyCallback = t =>
{
throw new NotImplementedException(
"StructureMapDependencyResolver is not configured!");
};
public static Func<Type, IEnumerable<object>> GetServicesViaDepencencyCallback = t =>
{
throw new NotImplementedException(
"StructureMapDependencyResolver is not configured!");
};
public object GetService(Type serviceType)
{
return GetServiceViaDepencencyCallback(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return GetServicesViaDepencencyCallback(serviceType);
}
}
Thrown error:
StructureMap Exception Code: 202 No
Default Instance defined for
PluginFamily
System.Web.Mvc.IControllerFactory,
System.Web.Mvc, Version=3.0.0.0,
Culture=neutral,
PublicKeyToken=31bf3856ad364e35
In MVC3, the DependencyResolver (which is a service locator) is used to attempt to locate an applicable type. If it cannot find a type, then it resumes looking through using the legacy code, which is the ControllerBuilder.Current instance. The important thing here is that it checks via the DependencyResolver, your StructureMap container. MVC3 requires that the DependencyResolver returns null for when it cannot find a type, it won't be the framework's responsibility to catch any exceptions from your container.

Categories