Add option to pass in existing builder.
See original GitHub issueCurrently, a new ContainerBuilder is created by the AutofacServiceProviderFactory.
I have a situation in which i want to pass in an existing builder. I have a Windows Service running using TopSelf. The topshelf application hosts various things (2 WCF services) and I also want to host a WebApi from the service. The service itself is already configured using Autofac and I want the WebApi to use the same container.
I achieve running the WebApi by registering:
builder.Register(c =>
{
return WebHost.CreateDefaultBuilder()
.ConfigureServices(s => s.AddAutofac())
.UseHttpSys()
.UseSerilog(c.Resolve<ILogger>())
.UseStartup<Startup>()
.Build();
})
.As<IWebHost>()
.SingleInstance();
and then in my main class resolving an IWebHost
and calling Start()
. This all works. However, the s.AddAutofac()
method creates a new AutofacServiceProviderFactory
which creates a new ContainerBuilder
. I would like something along the lines of:
builder.Register(c =>
{
return WebHost.CreateDefaultBuilder()
.ConfigureServices(s => s.AddAutofac(builder))
.UseHttpSys()
.UseSerilog(c.Resolve<ILogger>())
.UseStartup<Startup>()
.Build();
})
.As<IWebHost>()
.SingleInstance();
Issue Analytics
- State:
- Created 6 years ago
- Comments:5 (1 by maintainers)
Top Results From Across the Web
Builder with conditional inclusion of element - java
I'd like to resolve condition where I have it without over-engineering builder and without overcoding for every complex condition check. upd: ...
Read more >Solved: How do I pass arguments in a Builder design pattern
Suppose I have user input values that I don't know ahead of time and I want to pass these values while creating the...
Read more >@Builder
@Builder with @Singular adds a clear method since lombok v1.16.8. ... In the builder: A build() method which calls the method, passing in...
Read more >Builder pattern in multiple stages
There a few options the way I see it: Option 1: Pass the Builder Around. There's no benefit in actually building and returning...
Read more >Builder Design Pattern in Java
Let's see how we can implement builder design pattern in java. First of all you need to create a static nested class and...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@Strizzi12 and other interested.
I’ve debated with my coworker and we came up with the following solution:
I have 3 project:
-Project A: Code for an AspNetCore WebApi + DI Modules for Project A -Project B: Main application code requiring WCF services to be injected. -Project C: Hosting project using Topshelf for running application as a Windows Service + DI modules for both Project B and Project C + main DI “Installer”
Project C is the application entry point. The first thing that it does is call “Initialize” on my DI container. We’re using Autofac so I’m going to have that in my example code:
“Project B Module(s)” and “Project C Module(s)” are regular Autofac modules (available in some way or form in other DI containers aswell) and have nothing to do with AspNetCore. I register regular dependencies there and set up everything required for my main application, WCF hosting etc. The main entry point after DI has ran, is a “Host” class (which gets started by Topshelf) which looks a bit like this:
Both the WCF services and the IWebHost get injected neatly, no static references required. In order to achieve this, I register IWebHost in “Project C Module that initializes Project A” which looks something like the following:
I used the existing builder action of the
AddAutofac()
extension to add dependencies I know I need (and want) in my WebApi Project to the container created by the extension. Also,Startup
is a class defined in Project A (hence theusing "Project A";
at the top) which is the default startup class and looks like this:This way, the WebApi “Project A” has its own DI container, dependencies setup etc. but dependencies that need to be shared from the main Host to the WebApi project get “sideloaded” during webhost creation. I hope this helps (I did not post on Stack Overflow btw).
NOTE: All projects are .NET 4.6.2 projects in my case. I created a new empty project and manually imported all AspNetCore packages via nuget instead of using the Visual Studio Template for this. The default template creates a .NetCore project which can’t be referenced by a .Net Framework project (which my “Project C” is). You have to take this into acount, depending on your own application layout.
In thinking about adding something like this, we have to consider things like…
IServiceCollection
(their version ofContainerBuilder
) to register dependencies. If we add something like this, are we going to have difficulty keeping that support later?ContainerBuilder
is being shared around like this? What happens if someone tries building theContainerBuilder
themselves after theStartup
class has already run? (You can only build the container once, right?)Getting down to more specifics, I can say:
AddAutofac
, theStartup
class is going to callContainerBuilder.Build()
at the end of startup. So the proposed code snippet wouldn’t actually work - you’d get an exception during host startup when the host tries to build the container saying that the container has already been built.Startup
because theAddAutofac
stuff masks all that. You’d only ever have the .NET Core dependency resolver after that. Ostensibly if you need support in WCF and Web API, you’ll need a reference to a single built container. You won’t get that withAddAutofac
.The question becomes, then, “How do I share a container across ASP.NET Core, Web API, and WCF?”
Am I characterizing that all correctly? If not, let me know.
If I am, though, this is a great question to ask on StackOverflow. Your use case is pretty far outside the realm of “standard use cases,” to be sure. I can try to give you some pointers, but I don’t really have time to go all the way into full code snippets.
I would imagine the answer will involve…
AddAutofac
for the web host. You need more control over when theContainerBuilder
actually builds. Follow the quick start withoutConfigureContainer
.Yeah, it’s going to be pretty complicated. To be honest, if it was me, I wouldn’t try mixing all of these things in one app. I recognize there are business reasons to do things and you may have the need, I’m just saying, if it was me, I wouldn’t. ASP.NET Core handles REST calls just fine; I’d move everything out of Web API and into ASP.NET Core. WCF is a trickier thing, but I might consider having two services instead of a single service - one for the ASP.NET Core and one for the WCF. Instead of forcing the square peg into the round hole, I’d probably sidestep the problem entirely.
Does this help?