Resolving dependencies in ServiceRoute with Unity on an ASP.NET MVC project - wcf

I have a WCF service that I expose via REST using ServiceRoute in an ASP.NET MVC project:
routes.Add(new ServiceRoute("Rest", new WebServiceHostFactory(), typeof(ServeiInventaris)));
In my controllers, I use Unity to resolve dependencies. Is there a way to integrate Unity with ServiceRoute to let it resolve my dependencies (the dependencies of the REST service)?

Yes, you can. The solution is custom service host factory. Here is descibed complete solution. Neovolve blog We are using it successfully for one year.

Related

Is IHttpClientFactory registered in Asp .Net Core 3 by default?

I'm working on Asp.Net Core 3.1 project and it seems that it's possible to resolve an instance of IHttpClientFactory via DI without adding Microsoft.Extensions.Http package to my project and without registering the middleware (via AddHttpClient() method).
public ServiceClientProxy(IHttpClientFactory httpClientFactory)
{
this.httpClientFactory = httpClientFactory; // it just works
}
In the previous versions of Asp.Net Core the additional setup was required (installing nuget, registering the middleware).
Does it mean that this service is registered in DI by default automatically under the hood in version 3.1?
Does it make sense to call AddHttpClient() explicitly in the project's middleware?
The ability to resolve IHttpClientFactory via DI without adding Microsoft.Extensions.Http package to my project can be caused by the fact that other third party services used in my project call AddHttpClient() in their code.
In case an empty Asp.Net Core 3.1 project is created, IHttpClientFactory instance cannot be resolved via DI without proper registration in Startup.cs
So it makes sense to explicitly call AddHttpClient() method in Startup.cs

How to use Service Fabric service with AspNet Core WebApi and Autofac and run TestServer

I can't figure out how to use an AspNet Core 3.1 Web Api with Service Fabric and Autofac, and also how to have it ready for a TestServer to run for integration/functional testing.
The documentation is very incomplete.
Autofac documentation shows how to modify Program.cs to build autofac container, but it does not mention anything about the Startup.cs class that all the web api have:
https://autofaccn.readthedocs.io/en/latest/integration/servicefabric.html
Also the only example that Autofac has for service fabric is not a web api: https://github.com/autofac/Examples/tree/master/src/ServiceFabricDemo
There are other questions without valid answers:
Service Fabric AspNet Core 3.1 Autofac WebHostBuilder
Does anybody have any example on how to achieve this?
I can achieve the following (please see my GitHub repository with the sample)
Service fabric with stateless AspNet Core WebApi project (dotnet core 3.1)
Using Microsoft Dependency Injection to register services
Using TestServer to run integration tests on the http endpoint, and able to overwrite dependency injection registrations in a clean way without having to create another Startup class
I want the exact same, but using Autofac as DI container.
UPDATE 1:
I can't add Autofac to a WebHostBuilder and the ConfigureServices(IServiceCollection services) must be void as per AspNet Core 3.1+, so this is where I'm stuck. How to replace MS Dependency Injection in my sample
Event after the bounty there is not an answer to this. Maybe it's not possible as service fabric requires WebHost and not generic host.
In any case, I managed to have it working with older versions. Here's my repository where I show a sample on how to run AspNetCore2.1 with DotNetCore2.1 (LTS) and Autofac under Service Fabric. I use the webhost builder, not the generic one.
https://gitlab.com/sunnyatticsoftware/training/sasw-aspnetcore-testing/-/tree/master/aspnetcore2_1_autofac_servicefabric
Still, it'd be nice to eventually have a valid answer to the question.
I have NO idea if this works for the TestServer. It does however work fine with during ordinary hosting.
The exact thing you are looking for would be this line: services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<ContainerBuilder>>(new AutofacServiceProviderFactory(null)));
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[]
{
new ServiceInstanceListener(
serviceContext => new KestrelCommunicationListener(
serviceContext,
(url, listener) =>
{
return WebHost
.CreateDefaultBuilder()
.ConfigureServices(services =>
{
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<ContainerBuilder>>(new AutofacServiceProviderFactory(null)));
services.AddSingleton(serviceContext)
})
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.UseUniqueServiceUrl | ServiceFabricIntegrationOptions.UseReverseProxyIntegration)
.UseStartup<TStartupType>()
.Build();
}))
};
}
Hope it helps, it took me quite a while to arrive at this solution.

Using WebApi and structure map dependency injection

Although there are so many question on stack overflow which tends similar to my this question but no one is resolving my problem
I was using an MVC4 internet application wherein i had few MVC controller and for dependency injection i was using Structure map. Although dependency injection works fine with MVC controller but when i added an WebApi controller in the same MVC internet application and using the same parameter in constructor of WebApi controller as what i am using in MVC controller but dependency injection is not working with WebApi controller, although if i don't use dependency injection for WebApi controller(parameterless constructor), then it works fine, but for WebApi dependency injection(parameterized constructor) it is throwing an error No parameter less constructor is found.
Conclusion depedencies are not being injected for WebApi Controller in Internet(MVC application).
Few articles suggested to use DependencyResolver.SetResolver(). i used but did not resolve the issue.
The reason why WebApi controller were not working is as following:
Since MVC Controller uses different DependenyResolver instance that is the part of System.Web.MVC .dll and within the System.Web.MVC namespace
http://msdn.microsoft.com/en-us/library/system.web.mvc.idependencyresolver(v=vs.98).aspx
Where as Api Controllers uses DependencyResolver instance that is part of System.Web.Http.
http://msdn.microsoft.com/en-us/library/system.web.http.dependencies.idependencyresolver(v=vs.108).aspx
MVC and WebAPI controllers have a different way of setting their dependency resolver. This is how I set my dependency resolver for Unity:
public void ConfigureForMvc4()
{
DependencyResolver.SetResolver(
new UnityMvc4.UnityDependencyResolver(Container));
}
public void ConfigureForWebApi()
{
GlobalConfiguration.Configuration.DependencyResolver =
new UnityWebApi.UnityDependencyResolver(Container);
}
You need to add Dependency Injection files for WebApi
Install NuGet StructureMap.WebApi2 and in the App_Start/WebApiConfig.cs file, call StructuremapWebApi.Start();
Refer: https://www.exceptionnotfound.net/setting-up-dependency-injection-in-web-api-with-structuremap/

s#arp repository constructor injection for wcf service/client

I understand there is a s#arp contrib collection of dlls but not much documentation (as far as I can see). I intend to use the s#arp architecture in a wcf service (console app hosted). Could someone please provide some code that shows me how to (constructor) inject a repository into a wcf service/client? Is there a transaction attribute for wcf methods similar to that for controller actions in asp.net mvc? Thanks.
PS:
The northwind example:
northwind
supposedly contains an example but the downloaded vs solution does not load properly.
Haven't used WCF in a while, but follow the steps here:
https://github.com/sharparchitecture/Sharp-Architecture-Contrib/wiki/preparing-your-application-to-use-attributes-with-Castle-facilities
You need to add the initialisation code at the start of the app.
Instead of downloading the dlls, just add them using nuget. from the nuget package manager console:
install-package SharpArchContrib.Core
install-package SharpArchContrib.Domain
install-package SharpArchContrib.Castle
There is some documentation about the transaction attribute here, which should provide a starting point WCF:
https://github.com/sharparchitecture/Sharp-Architecture-Contrib/wiki/Transaction-attribute-%28supports-nhibernate-or-system.transaction.-works-with-asp.net%2C-wcf%2C-windows-gui-and-windows-service-applications%29
Chris Richards has posted an example on how to use SharpArch in WCF Console App
https://github.com/yellowfeather/TestWcfService

Ninject Di bindings using a WCF service

I recently created a WCF service library. I am planning on hosting it in IIS. Since I want to reuse my repository layer I decided to go use Ninject in my WCF service as well (I use it in other projects in the solution).
I installed the Ninject Wcf Extensions. I configured it using the NinjectServiceHostFactory in the svc file. I added a Global.asax file to override the CreateKernel() that inherits from NinjectWcfApplication but I am not sure if I am using the bindings correctly. I first started with:
Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
But I quickly realized that this does not work since no data was saved to my database. It appears that the WCF service does not use the ASP.NET pipeline. I went ahead and tried both of these as well just to see if my data was committed to the database:
Bind<IUnitOfWork>().To<UnitOfWork>().InThreadScope();
Bind<IUnitOfWork>().To<UnitOfWork>().InTransientScope();
No luck. I then decided to try:
Bind<IUnitOfWork>().To<UnitOfWork>().InSingletonScope();
This worked but I don't want my database context to be shared by every single request that comes in to the WCF service. I then did some research and found the following approach:
Bind<IUnitOfWork>().To<UnitOfWork>().InScope(c => OperationContext.Current);
This works but is it correct? I wan t something to resemble the InRequestScope for a MVC application. Each request to the service should get its own Database context.
I suggest to have a look at the latest build from the CI-Server http://teamcity.codebetter.com
You need Ninject, Ninject.Web.Common, Ninject.Extensions.Wcf
With this version you can use InRequestScope for Wcf.
I am new to Ninject, but I can tell you that OperationContext.Current is the equivalent to HttpContext.Current for web application.
So your first thought was to use .InRequestScope(); (which is equivalent to .InScope(c => HttpContext.Current);)
so I guess that using .InScope(c => OperationContext.Current); for WCF is pretty correct.