I am trying to port an asp.net application to asp.net core. I have property injection (using ninject) on my UnitOfWork implementation like this.
[Inject]
public IOrderRepository OrderRepository { get; set; }
[Inject]
public ICustomerRepository CustomerRepository { get; set; }
Is there a way to achieve the same functionality using build in DI on .net core? Also is it possible to use convention based binding?
No, the built-in DI/IoC container is intentionally kept simple in both usage and features to offer a base for other DI containers to plug-in.
So there is no built-in support for: Auto-Discovery, Auto-Registrations, Decorators or Injectors, or convention based registrations. There are also no plans to add this to the built-in container yet as far as I know.
You'll have to use a third party container with property injection support.
Please note that property injection is considered bad in 98% of all scenarios, because it hides dependencies and there is no guarantee that the object will be injected when the class is created.
With constructor injection you can enforce this via constructor and check for null and the not create the instance of the class. With property injection this is impossible and during unit tests its not obvious which services/dependencies the class requires when they are not defined in the constructor, so easy to miss and get
NullReferenceExceptions
.The only valid reason for Property Injection I ever found was to inject services into proxy classes generated by a third party library, i.e. WCF proxies created from an interface where you have no control about the object creation.
Avoid it everywhere else.
No, but here is how you can create your own
[inject]
attributes with the help of autofac's property injection mecanism.First Create your own
InjectAttribute
:Then create your own
InjectPropertySelector
that uses reflection to check for properties marked with[inject]
:Then use your selector in your
ConfigureServices
where you wire up yourAutofacServiceProvider
:Finally in your service you can now use
[inject]
:You surely can take this solution even further, e.g. by using an attribute for specifying your service's lifecycle above your service's class definition...
...and then checking for this attribute when configuring your services via autofac. But this would go beyond the scope of this answer.