Autofac构造函数/属性注入疑问:DI/IoC新手技术咨询
Hey there! Great choice picking Autofac—it's a solid, flexible container, and it makes sense to start with something that works across both .NET Framework and Core. Let's tackle your two questions clearly:
You're exactly right here: Autofac (or any DI container) can only handle constructor injection for objects that the container itself creates. If you manually instantiate an object with new MyClass() in your code, the container has no awareness of that instance, so it can't automatically inject its constructor dependencies.
Let's break this down for your scenarios:
- Controllers/WCF Services: If your controller or WCF service is being created by the framework host (ASP.NET Core, ASP.NET Framework, or WCF's runtime), and you've registered that type with Autofac, the container will take over instantiation. That's when constructor injection works seamlessly—Autofac resolves all the dependencies in the constructor and passes them in.
- Manual
newcalls: If you write something likevar myCustomObject = new MyCustomObject()inside a controller action or service method, thatmyCustomObjectinstance is outside the container's control. Autofac can't go back and inject its constructor parameters after you've created it.
What to do instead?
- Let the container create it: Instead of manually
newing, resolve the object from the container (e.g.,var myCustomObject = container.Resolve<MyCustomObject>()), or better yet, injectMyCustomObjectas a dependency into the class where you need it (via constructor injection) instead of creating it yourself. This keeps everything within the DI pipeline. - Manual injection (last resort): If you absolutely have to create the object manually, you can resolve its dependencies from the container and pass them to the constructor yourself—but this defeats the purpose of using DI, so try to avoid it.
Property injection is possible in Autofac, but keep in mind: constructor injection is almost always the better choice because it makes a class's dependencies explicit and ensures they're present when the object is created. Use property injection only for optional dependencies or when you can't modify a class's constructor (e.g., legacy code).
Here's how to set it up for different scenarios:
For Regular Classes
First, define a public property in your class (no attribute is required, but you can use [Autofac.Core.Inject] if you want to be explicit):
public class MyBusinessService { // Optional: Mark with [Inject] to explicitly indicate this should be injected public ILogger Logger { get; set; } }
Then, when registering the class with Autofac, use the PropertiesAutowired() method to tell the container to inject its properties:
var builder = new ContainerBuilder(); builder.RegisterType<ConsoleLogger>().As<ILogger>(); // Enable property injection for MyBusinessService builder.RegisterType<MyBusinessService>().PropertiesAutowired();
If you only want to inject a specific property, use WithProperty() instead:
builder.RegisterType<MyBusinessService>().WithProperty("Logger", new ConsoleLogger());
For ASP.NET Controllers
ASP.NET Core
When registering controllers with Autofac, chain the PropertiesAutowired() method to enable property injection:
builder.RegisterControllers(typeof(Startup).Assembly).PropertiesAutowired();
Then, in your controller, just define a public property for the dependency:
public class HomeController : Controller { public IMyService MyService { get; set; } public IActionResult Index() { // MyService will be injected by Autofac return View(); } }
ASP.NET Framework (MVC)
Similar to Core—register controllers with PropertiesAutowired():
builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
For WCF Services
If you're using Autofac's WCF integration, enable property injection when registering your service:
builder.RegisterType<MyWcfService>().As<IMyWcfService>().PropertiesAutowired();
Make sure you've configured WCF to use Autofac's instance provider (this is part of setting up Autofac with WCF) so the container creates the service instances and handles injection.
内容的提问来源于stack exchange,提问作者cantdoanything33

