MediatR Autofac Handler registration in Container - mediatr

I'm running into an issue in my first IMediatR, Autofac MVC project. Help is much appreciated.. Thanks in advance !!!
Handler was not found for request of type
SliceProject.Services.Query.GetUserListQuery. Container or service
locator not configured properly or handlers not registered with your
container.
Autofac Container Code:
builder
.RegisterAssemblyTypes(typeof(IRequest<>).Assembly)
.Where(t => t.IsClosedTypeOf(typeof(IRequest<>)))
.AsImplementedInterfaces();
builder
.RegisterAssemblyTypes(typeof(IRequestHandler<,>).Assembly)
.Where(t => t.IsClosedTypeOf(typeof(IRequestHandler<,>)))
.AsImplementedInterfaces();

That's because you're telling Autofac to look in the assembly that contains the IRequestHandler<TRequest, TResponse> type. That type lives in the MediatR assembly, so there's no chance your handlers live in that assembly.
You have to chance the registration so it look in the assembly(ies) where your handlers are defined. If they're all defined in one single assembly, pick one handler and use it as a marker type. I tried to guess the name of one of your handlers here:
builder
.RegisterAssemblyTypes(typeof(GetUserListQueryHandler).Assembly)
.Where(t => t.IsClosedTypeOf(typeof(IRequestHandler<,>)))
.AsImplementedInterfaces();
Please also note that the registration can be made simpler with a funciton provided by Autofac, AsClosedTypesOf. It does exactly the same thing.
builder
.RegisterAssemblyTypes(typeof(GetUserListQueryHandler).Assembly)
.AsClosedTypesOf(typeof(IRequestHandler<,>)));
Finally, and this is a bit unrelated, but why do you try to register your requests in the container? Requests are usually created by custom code and not resolved from the container. In your case, it also has no effect since you made the same mistake as for handlers, that is looking for requests in the MediatR assembly, which doesn't contain any implementations of IRequest<TResponse>.

Related

Register and Resolve DI containers in Prism 7 - Xamarin Forms

I'm using prism 7 for my new xamarin forms application.I have gone through this document.
I have couple of questions:
There are few DI interfaces I register after the app starts. We can use IContainerRegistry in app.xaml.cs to register but if we want to register or resolve in other pages, is there any way to get do it other that saving the IContainerRegistry and IContainerRegistry instance from app.xaml.cs and using it where ever we want?
To register a type the syntax is :
ContainerRegistry.RegisterInstance<ITextService>(new TextService());
But how can we register a singleton?
I saw few examples but I did not really understand how to do it? can anyone please show an example?
UPDATE:
To register a singleton,
The syntax seems like
containerRegistry.RegisterSingleton<ILoggerFacade, EmptyLogger>(); but if we just pass the type without creating an instance ( in this case, the instance of EmptyLogger), how can we use properly register them?
To register a type the syntax is: ContainerRegistry.RegisterInstance<ITextService>(new TextService());
this registers an instance not a type, btw, to register a type do ContainerRegistry.Register<IAnInterface, SomeImplementation>();
But how can we register a singleton?
ContainerRegistry.RegisterSingleton<ITextService, TextService>(); does this, and btw, an instance is a singleton by nature (because the di container always has to inject the one instance you registered as it cannot create new instances on its own)
is there any way to get do it other that saving the IContainerRegistry and IContainerRegistry instance from app.xaml.cs and using it where ever we want?
I recommend registering everything in one place rather than scattering registrations all over the project. But if you're determined, you can have IContainerRegistry injected anywhere and register your stuff.

NavigationService Xamarin with Prism and Autofact can't find my navigation

I register my Xamarin form page with Autofac container on my App that inherits PrismApplication för Autofac
_container.RegisterTypeForNavigation<MasterLayoutPage_View, MasterLayoutPageViewModel>("MasterLayoutPage");
Then I navigate like this:
await NavigationService.NavigateAsync("MasterLayoutPage");
But it always says that MasterLayoutPage is not registered.
But when I check my Container for registered types it's there, fully added as the registration above.
Have I missed something? It worked with Unity I just change to Autofac.
I found this kind of odd and wonder if it might be a bug or if NavigationService with Autofact can't register the type as Unity can?
Seems like my problem was that I did not register the pages inside the override method RegisterTypes on App.xaml.cs I registered the types on the Initialize overridden method. It did work with Unity, not sure why it does not work the same way with autofac when it's the same container I use... Maybe prismApplication for unity has some difference then PrismApplication for Autofac, I shall take a look at the implementations of those two

Webapi DefaultHttpControllerSelector does not properly resolve my controller

I have an WebApi application that contains some controllers (they are registered using the extension method RegisterApiControllers). This application references another assembly that contains other controllers that I don't want to expose(I have checked that they are not registered in the container). It happens that both have an OrderController, and when I try to access the /api/Order url, I get an exception "Multiple types were found that match the controller named 'order'." and the stack trace shows that I was in DefaultHttpControllerSelector.
I have seen that AutofacControllerFactory used to exist and there was even a ConfigureWebApi that registered it, but it is not anymore present in the default branch.(you can see it here http://alexmg.com/post/2012/03/09/Autofac-ASPNET-Web-API-(Beta)-Integration.aspx)
It seems also that we can not filter the namespace of the route definition in WebApi (it is possible to MVC).
So any idea on how I can use only the Controller registered in my Autofac container and not use the DefaultHttpControllerSelector that seems to scan all referenced assemblies to discover controller?
Thanks
The problem is that registering the controller with autofac is not really related to the routing process. Only once the routing process has identified which controller to dispatch to will Autofac be called to resolve the type.
It looks like, from digging around in the source, that you would need to write a replacement IHttpControllerSelector in order to handle two controllers with the same name. (which really sucks BTW).
You might be able replace the DefaultHttpControllerTypeResolver with an instance that is passed a predicate that filters out the controllers from the assembly that you want to ignore. It's a bit of a kludgy solution but might work.
Actually, you might be able to replace the DefaultHttpControllerTypeResolver completely with one that is based on registrations in your Autofac container. It is a very simple interface, so as long as Autofac have a some kind of discovery mechanism, you should be golden.
public interface IHttpControllerTypeResolver
{
ICollection<Type> GetControllerTypes(IAssembliesResolver assembliesResolver);
}

NServiceBus/MVC injection - Autofac doesn't like IControllerFactory?

all. I am getting started with NServiceBus and have a pretty good handle on the basics thanks to Pluralsight and the internet. I have an stock MVC 4 project and I have setup dependency injection for my controllers (thanks to this blog post).
Here is how I have my bus setup in Global.asax:
_bus = Configure.With()
.DefaultBuilder()
.ForMVC()
.Log4Net()
.XmlSerializer()
.MsmqTransport()
.UnicastBus()
.SendOnly();
I am assigning it to a local private variable because I need access to the bus in Global so I can do some stuff on Session_End. However, when I run, I get the following error:
The requested service 'System.Web.Mvc.IControllerFactory' has not been
registered. To avoid this exception, either register a component to
provide the service, check for service registration using
IsRegistered(), or use the ResolveOptional() method to resolve an
optional dependency.
According to my stack trace, the failure point is when Autofac tries to resolve the type. For the sake of sanity, I removed the private variable and used just the Configure statement, same thing. I also have Ninject wired up in this app because that is my IoC of choice. Thinking that it was interfering with Autofac in some way, I removed Ninject from the equation, still not working.
So my question is, what am I doing wrong? Am I missing something? This is my first time with NServiceBus, but from everything I've seen, this should just work. Any info would be super helpful. Thanks.
Have a look at our MVC4 sample (this is running against v4, the next major release):
https://github.com/NServiceBus/NServiceBus/tree/develop/Samples/Messaging.Msmq/MyWebClient
I found the solution from your code, John! Here was my issue. This is what I had in my Dependency Resolver Adapter:
public object GetService(Type serviceType)
{
_builder.Build(serviceType);
}
What I needed to do was what you did in your MVC4 example:
public object GetService(Type serviceType)
{
return (Configure.Instance.Configurer.HasComponent(serviceType)) ? _builder.Build(serviceType) : null;
}
Once I did that, it all sorted itself out. Thanks again for the help!

How to pass an HttpContext to a dependency initialization in MVC3 application

I am using Ninject in MVC3 application.
One of my resolvable dependencies makes use of HttpContext.Current.Server.MapPath("~/App_Data")
Back when I was initializing an IoC container in Global.asax (Application_Start), I was able to just define in my module configuration:
.WithConstructorArgument("basePath", HttpContext.Current.Server.MapPath("~/App_Data"));
Since my module was being initialized from the same thread as the Application, HttContext.Current wasn't null.
Then I had to move my Dependency Injection initialization to an PreAppStart method, using the WebActivator. Since the HttContext is not yet available in this scenario, I had to remove the parameter initialization of my dep.
I had worked around the problem by resoling the HttpContext inside my class instance at runtime. But it turns out it was possible only as long as the instance was being called from the Request Thread. As soon as I have moved the resolved instance call to a separate thread (not to be halting the Controllers' ActionResult generation), I arrived at the same problem - no longer able to get HttpContext. How can I resolve it in my scenario?
P.S. Just figured out I still can just call a method on my dependency from Global.asax Application start and feed the HttpContext from there. Nevertheless, let me know which is the best way to do it.
There should be a way in Ninject to register the dependency in a lazy way using a delegate. This way it will only resolve it when you access the dependency.
Here is how I do it using StructureMap:
For<HttpContextBase>().Use(c => new HttpContextWrapper(HttpContext.Current));
As far as accessing the HttpContext from a different thread, you can use the AsyncManager.Sync(d) method that takes a delegate and runs it in the ASP .NET worker process.

Resources