How to register HealthCheck in Autofac module - .net-6.0

Im using .NET 6 and Autofac to register my dependencies, all works great.
However I was wondering how can I register a healthcheck in my module (not in the startup.cs), ex:
public class InfrastructureModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ApplicationDbContext>().InstancePerLifetimeScope();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope();
// builder.AddCheck<MyServiceHealthCheck>("Service ACheck"); <- not working
}
}

Short answer is: you can't. You can't mix and match Microsoft registrations with Autofac registrations like that. That's why there's ConfigureServices separate from ConfigureContainer.
Longer answer is: if you want to go spelunking through the code of AddHealthCheck and figure out what it's doing under the covers, you could make your own Autofac version of that and it would work. But it's work for you to do, not something Autofac provides, and it'd be supported only by you.
However, reading the intent of the question, it sounds like you want to do MS registrations in an Autofac module and that's not a supported thing.

Related

Shiny + Prism + Platform Service Example

I am attempting to update a Prism 8.1 app to use Shiny v2.
In trying to turn one of my services into a Job I keep getting a container resolution error (using Unity). I am not sure what the pattern is for registering platform implementations of services. The Job has a service that is from my platform project but at the time the services.RegisterJob() is called I guess the platform initializer has not run.
Can someone post an example of how you are supposed to register platform implementations with Shiny?
Well, I'm not sure if this is the intended design but I solved the platform services this way.
I added a constructor parameter to my ShinyStartup like this:
public Startup(IPlatformInitializer platformInitializer) : base(PrismContainerExtension.Current)
{
_platformInitializer = platformInitializer;
}
and then in my AppDelegate I used this:
Shiny.ShinyHost.Init(new Shiny.ApplePlatform(), new Startup(new iOSInitializer()));
Where iOSInitializer is my Prism IPlatformInitializer.
Then in Startup I added:
protected override void RegisterServices(IContainerRegistry containerRegistry)
{
_platformInitializer.RegisterTypes(containerRegistry);
...
}
As far as the IJob not resolving dependencies when using RegisterJob, I moved job registration to App.OnStart using IJobManager.Register and it works. Also not sure if this is the intended design.
I did all my container wire up before calling RegisterJob and it still failed to resolve so there must be something under the covers that is happening in the Prism+Shiny world.

Using Activity Result API in Xamarin.Android

It seems like it's not properly supported as I need to implement JNI stuff when I try to implement IActivityResultCallback interface. Also ActivityResultContract is not a generic class so when I inherit it to create a custom contract it's not type-safe like in native Android. So it's not usable at all at the moment I guess?
You can get around this issue by inheriting from Java.Lang.Object. Something like this will probably work:
public class MyActivityResultCallback : Java.Lang.Object, IActivityResultCallback
{
}
IActivityResultCallback inherits from IJavaObject, which most, if not all Android interfaces do. This way Xamarin can interface between C# and Java. This is described pretty well here: https://learn.microsoft.com/en-us/xamarin/android/platform/java-integration/working-with-jni#implementing-interfaces

NServiceBus and ApiController

i try to configure my NServiceBus for a WebApi. I've tried this one: https://coderkarl.wordpress.com/2012/03/16/injecting-nservicebus-into-asp-net-webapi/
The Problem is the Syntax has been changed in the newest NServiceBus-Versin. I can't use the Functions for the Configure-Class because they will be removed in further Versions. The new way to configure the Bus is using the BusConfiguration-Class but i have no idea how.
Here is the older Code:
public static Configure ForWebApi(this Configure configure)
{
// Register our http controller activator with NSB
configure.Configurer.RegisterSingleton(typeof(IHttpControllerActivator),
new NSBHttpControllerActivator());
// Find every http controller class so that we can register it
var controllers = Configure.TypesToScan
.Where(t => typeof(IHttpController).IsAssignableFrom(t));
// Register each http controller class with the NServiceBus container
foreach (Type type in controllers)
configure.Configurer.ConfigureComponent(type, ComponentCallModelEnum.Singlecall);
// Set the WebApi dependency resolver to use our resolver
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NServiceBusResolverAdapter(configure.Builder));
// Required by the fluent configuration semantics
return configure;
}
And Application_Start():
AreaRegistration.RegisterAllAreas();
// Use LocalDB for Entity Framework by default
Database.DefaultConnectionFactory = new SqlConnectionFactory("Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True");
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
BundleTable.Bundles.RegisterTemplateBundles();
Configure.WithWeb()
.DefaultBuilder()
.ForWebApi() // <------ here is the line that registers it
.Log4Net()
.XmlSerializer()
.MsmqTransport()
.IsTransactional(false)
.PurgeOnStartup(false)
.UnicastBus()
.ImpersonateSender(false)
.CreateBus()
.Start();
Does someone has managed it for the NServiceBus Version 5?
As wlabaj says, the documentation on the particular website says it all. Almost.
We use AutoFac so we don't need any direct reference to IBus or ISendOnlyBus and therefor we do this
ContainerBuilder builder = new ContainerBuilder();
var container = builder.Build();
configuration.UseContainer<AutofacBuilder>(x => x.ExistingLifetimeScope(container));
What we do in WebAPI and ASP.NET applications is this
NServiceBus.Bus.CreateSendOnly(configuration);
Because it's not a good practice to expect reply messages to come back after sending them.
Here you can see 3.0 vs 4.0 vs 5.0 configuration syntax. At the top of the page you have a link to download code samples.
The examples are for ASP .NET though, so you'll need to tweak it slightly for WebAPI. Let me know if you need further help with that.
ForWebApi was never a part of NServiceBus, this was an extension method from the sample that was used to configure NServiceBus dependency resolver to instantiate controllers. The way how it was done is shown here.
There is no need to use NServiceBus resolver since it is just a wrapper around another container. By default it uses Autofac, so you can just use Autofac to work for you in the whole application.
Autofac WebAPI integration is properly described in the documentation.
NServiceBus documentation has a page about using your own container.
This is a very well known setup that you can easily implement.

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!

Use Container/DependencyResolver in other dll

I'm trying to get myself familiar with MVC3 and autofac but I've encountered small problem that I'm having trouble resolving.
I am using autofac integrated with MVC3 and all works well, pages are loading correctly, dependencies are being injected and that's cool. What's bugging me is how to use autofac's Container or MVC's DependencyResover in class library project.
I'm trying to create static class that will help me handle domain events. I simply want to be able to call the method with event parameter and everything should be handeled by this class. Here is code:
public static IContainer Container { get; set; }
public static void Raise<T>(T e) where T : IDomainEvent
{
foreach (var eventHandler in DomainEventManager.Container.Resolve<IEnumerable<EventHandlers.Handles<T>>>())
{
eventHandler.Handle(e);
}
}
As you can see it's pretty straightforward and everything would work great if it wasn't MVC approach. Some of my dependencies are registeres as InstancePerHttpRequest (NHibernate' session), while other are registered as InstancePerDependency or SingleInstance. Thus when I try to use container created in my UI project, I get exception that there is no httpRequest tag available.
How can i reuse the Container created in web project to get access to all of it's features, including InstancePerHttpRequest and httpRequest tag?
Or maybe there is other solution to my problem? I was thinking about using delegate function to obtain event handlers, but I cannot (can I?) create generic delegate that I would not need to initialize with concrete type at time of assignment.
Why I want to do this using static class is basically every entity and aggregate or service needs to be able to raise domain event. Injecting EventManager into every one of these would be troublesome and static class is exactly what would resolve all my problems.
If anyone could help me get my head around it I would be grateful.
Cheers, Pako
You shouldn't be referencing your container directly from your app code. This looks like the Service Locator anti-pattern. The correct action is to pass your objects the services they need to do their jobs, usually done through constructor parameters. BUT... if you are going to insist on depending on a global static, then at least model EventManager as a singleton, such that usage would look like:
EventManager.Current.Raise<SomeEvent>(someObject);
and then you can set EventManager.Current equal to a properly constructed instance when your app is initialized.

Resources