I have around 6 WCF services that I want to host in an MVC application, routing requests to /services/foo to WcfFooService and /services/bar to WcfBarService
I can accomplish IoC with StructureMap within the services and inject my constructor dependencies by using the example that Jimmy Bogard blogged about here:
Jimmy's article is great, but I'm trying to extend it to work with multiple services hosted within the same MVC application. Essentially, the part at the bottom is the part that is causing me a few headaches:
public class StructureMapServiceHostFactory : ServiceHostFactory
{
public StructureMapServiceHostFactory()
{
ObjectFactory.Initialize(x => x.AddRegistry<FooRegistry>());
//var iTriedThisToo = ObjectFactory.Container;
//container.Configure(x => x.[etc]);
}
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new StructureMapServiceHost(serviceType, baseAddresses);
}
}
With a single WCF service - routing MVC requests to a specific url via the StructureMapServiceHostFactory shown above works brilliantly - but - If (for example) I create a StructureMapServiceHostFactory2 for the /services/bar call, to allow for a different Registry to be used, when the MVC app spins up, it appears to call each factory in turn as it runs through RouteConfig.cs and adds the routes, so ultimately I don't get configured instances that the first ServiceHostFactory should provide.
It doesn't make a difference if I call Initialize(); or attempt to grab the Container property and call Configure on it, either.
Am I on a hiding to nothing with this? The major reason for requiring registry isolation is due to different NHibernate configuration, but I could configure Named instances of SessionFactory and Session for NHibernate purposes and then use a single registry to get around this. In my mind I wanted the WCF service and MVC-hosting to be capable of using their own IoC containers in isolation, which is why I went down this route.
Is there any way that I can accomplish this?
Ok, so it would appear the only person capable of answering this was me, by virtue of a re-think and 're-architecting' the solution so that the problem doesn't exist in the first place.
I now have a capable way of hosting these services and maintaining IoC with StructureMap neatly per service, without any conflicting concerns.
If you find yourself in a similar position with SOA taking over (SOATO?) - taking a step back is a good start ;)
Related
I am currently working on a feature and added the builder code like this in the Autofac
builder.RegisterType<ILTLoPublisher<ScheduleUpdateEvent>>()
.AsImplementedInterfaces()
.InstancePerRequest()
.Keyed<IILTLoPublisher<ScheduleUpdateEvent>>(AuditType.Schedule);
builder.RegisterType<ILTLoPublisher<ScheduleUpdatePart>>()
.AsImplementedInterfaces()
.InstancePerRequest()
.Keyed<IILTLoPublisher<ScheduleUpdatePart>>(AuditType.Part);
builder.RegisterType<ILTLoPublisher<ScheduleUpdateTest>>()
.AsImplementedInterfaces()
.InstancePerRequest()
.Keyed<IILTLoPublisher<ScheduleUpdateTest>>(AuditType.Test);
This code is run as a console app service and the call to this is made from an api service.I want it to be called as below
AutoFacModule autofac = new AutoFacModule();
var builder = new ContainerBuilder();
autofac.LoadBuilder(builder);
Container = builder.Build();
using (var scope = Container.BeginLifetimeScope())
{
var _publisher1 = scope.ResolveKeyed<IILTLoPublisher<ScheduleUpdateEvent>>(AuditType.Schedule);
var _publisher2 = scope.ResolveKeyed<IILTLoPublisher<ScheduleUpdatePart>>(AuditType.Part);
var _publisher2 = scope.ResolveKeyed<IILTLoPublisher<ScheduleUpdateTest>>(AuditType.Test);
}
When i am trying to resolve it using the below code in my implementation class
var _publisher = scope.ResolveKeyed<IILTLoPublisher<ScheduleUpdateEvent>>(AuditType.Schedule);
I am getting the following error
Unable to resolve the type Apiconnector.Integrations.Vilt.Service.Providers.Custom.Publish.ILTLoPublisher`1[LMS.ILT.ScheduleUpdateEvent]' because the lifetime scope it belongs in can't be located
You can't use InstancePerRequest unless the object being resolved is part of a web request (as noted by the comments on the question). More specifically:
The executing application must be a web application.
The executing application needs to have the Autofac web integration in place.
The resolution must be happening in that web application as part of a response to an inbound web request - for example, as part of an MVC controller or ASP.NET Core middleware.
The "per request" semantics have nothing to do with the client making the request - it's about the server handling the request.
You might want to spend some time with the documentation on the topic. There is a section in there about how to implement custom per-request semantics for your app.
If what you are creating is a console app that takes in requests from clients (e.g., a self-hosted web application) then you need to:
Add the existing Autofac web integration for your app type (we do support ASP.NET Web API and ASP.NET Core self hosted scenarios); OR
Implement something custom if you're not using ASP.NET (see that doc I linked).
If what you are creating is a console app that issues requests as a client then you should ignore InstancePerRequest. Instead:
Create a new lifetime scope around each request (like you're doing) and treat that as a unit of work.
Register components as InstancePerLifetimeScope so there will be just one for the duration of that lifetime scope.
That said, without a minimal repro it's hard to see what you're doing beyond that to provide any sort of guidance.
Since you mentioned you're pretty new to all this, it would be very worth your time checking out the Autofac documentation to start understanding concepts like this as well as looking in the Examples repo where there are working examples of many different application types to show you how things work.
Is this possible to achieve?
I want to make a library (lets call it Foolib) that will automatically add an mvc controller with a fix route to all mvc applications that have a dependency on Foolib.
Foolib is to be used in several intranet applications that we are developing and I want to make sure that all applications that use of Foolib have an standard ability to receive a configuration object.
In Foolib there will be a controller something like:
public FooController
{
[Route("/Foo")]
public Post(object obj)
{
}
}
Would it be possible to register the controller automatically to all web applications that uses Foolib?
Normally the calls to register controllers are made in the Startup class, how would I hook in this extra controller, hopefully without having to burden the other mvc application developers with an "just add this line to your startup" solution?
According to the docs
"By default MVC will search the dependency tree and find controllers (even in other assemblies)."
So it should just work.
For pure code-based WCF configuration, in .NET 4.0 one could configure a base address for a service when creating an instance of a ServiceHost (assuming a self-hosted scenario, which is suitable for my needs). While one could still do this with .NET 4.5, MSDN implies that using the new Configure() method is a better practice because it makes such code-based configuration a bit easier for self-hosted and a lot easier for web hosted scenarios (see Configuring WCF Services in Code).
The problem, however, is that though the object you have to work with inside the Configure method (a System.ServiceModel.ServiceConfiguration) has a BaseAddresses property it is read-only. Surely there must be a way to set the base addresses in code? My web searches have turned up not only nothing about this specific question, but no articles or posts about this Configure method at all, except for the single MSDN page I have referenced!
Looking in reflector what BaseAddresses property does:
// System.ServiceModel.ServiceConfiguration
public ReadOnlyCollection<Uri> BaseAddresses
{
get
{
return this.host.BaseAddresses;
}
}
I was unable to find any other method in ServiceConfiguration working with ServiceHost.BaseAddresses
Instance of ServiceConfiguration is created using ServiceHost instance:
// System.ServiceModel.ServiceConfiguration
internal ServiceConfiguration(ServiceHost host)
{
ServiceConfiguration.CheckArgument<ServiceHost>(host, "host");
this.host = host;
}
This means that ServiceConfiguration is just an extension to standard way of configuring ServiceHost. So I would suggest any old way of setting BaseAddress is still considered as the best practice (programmatic or using configuration).
I'm trying to solve a problem I have with asynchronous event-based rest services. I have services that generate events in the application, and those events are handled asynchronouly. The problem I have is my linq to sql data contexts are disposed by then, because of autofac's lifetime scopes.
I found a website that had a solution for it and it involved getting the application wide container. He got it like so :
var accessor = ((IContainerProviderAccessor) HttpContext.Current.ApplicationInstance);
return accessor.ContainerProvider.ApplicationContainer;
However, I can't import IContainerProviderAccessor, which seems to be in autofac's mvc integration assembly. How can I translate this code for web api.
IContainerProviderAccessor is no longer supported. Autofac now use the IDependencyResolver of ASP.net MVC
If you want to access the resolver you can use the DependencyResolver.Current property of ASP.net MVC.
YourDbContext yourDbContext = DependencyResolver.Current.GetService<YourDbContext>();
Another solution would be to inject Func<Owned<YourDbContext>>, it will act as a factory. Each time you need a DbContext inside an API method you will be able to invoke it Autofac will instanciate a new one.
I have two projects in a solution. An ASP.NET Web Application and ASMX Web Service Application. ASMX Web Service is referenced in ASP.NET Web Application(As Web References).
In aspx page we create an object of Web Service and call methods on it like following.
MyWebService myWebService = new MyWebService();
UserDetail userDetail = myWebService.GetUserDetail(25);
This means my aspx page depends upon on concrete implementation of MyWebService. According to Dependency Inversion Principle (DIP), code should depend on abstractions, not concrete implementations and that those abstractions should not depend on details; the details should depend on the abstractions.
How do i remove this dependency?
On Google i came across following articles which is similar but not exactly to what i am looking for.
http://www.springframework.net/doc-latest/reference/html/webservices.html
http://www.codeproject.com/Articles/310677/ASP-NET-Web-Services-Dependency-Injection-using-Un
http://www.gitshah.com/2011/11/integrating-springnet-with-asmx.html
All these articles explains about injecting dependency into asmx web service and not injecting asmx web service dependency into asp.net web application.
I am newbie to term Dependency Injection and i may be thinking the wrong way and going in a wrong direction.
Plesae help me understand this confusion.
Why write this code on webpage?, you can write a layer to handle such calls and let that layer decide how to perform the operation.
This would allow you to:-
1)Loosely couple functionality.
2)Remove redundancy.
You can use a factory that's injected.
For example:
interface IWebServiceFactory
{
MyWebService client();
}
public class WebServiceFactory
{
public MyWebService client()
{
return new MyWebService();
}
}
In your asp.net web application.
var service = Locator.Resolve<IWebServiceFactory>();
UserDetail userDetail = service .GetUserDetail(25);
Note you need dependency injector in global ascx. you can ninject or ms unity or whatever injector.