Is there a way to achieve the same functionality using built-in DI on .NET Core?
No, but here is how you can create your own [inject]
attributes with the help of Autofac's property injection mechanism.
First create your own InjectAttribute
:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class InjectAttribute : Attribute
{
public InjectAttribute() : base() { }
}
Then create your own InjectPropertySelector
that uses reflection to check for properties marked with [inject]
:
public class InjectPropertySelector : DefaultPropertySelector
{
public InjectPropertySelector(bool preserveSetValues) : base(preserveSetValues)
{ }
public override bool InjectProperty(PropertyInfo propertyInfo, object instance)
{
var attr = propertyInfo.GetCustomAttribute<InjectAttribute>(inherit: true);
return attr != null && propertyInfo.CanWrite
&& (!PreserveSetValues
|| (propertyInfo.CanRead && propertyInfo.GetValue(instance, null) == null));
}
}
Then use your selector in your ConfigureServices
where you wire up your AutofacServiceProvider
:
public class Startup
{
public IServiceProvider ConfigureServices(IServiceCollection services)
{
var builder = new ContainerBuilder();
builder.Populate(services);
// use your property selector to discover the properties marked with [inject]
builder.RegisterType<MyServiceX>().PropertiesAutowired((new InjectablePropertySelector(true)););
this.ApplicationContainer = builder.Build();
return new AutofacServiceProvider(this.ApplicationContainer);
}
}
Finally in your service you can now use [inject]
:
public class MyServiceX
{
[Inject]
public IOrderRepository OrderRepository { get; set; }
[Inject]
public ICustomerRepository CustomerRepository { get; set; }
}
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...
[Injectable(LifetimeScope.SingleInstance)]
public class IOrderRepository
...and then checking for this attribute when configuring your services via Autofac. But this would go beyond the scope of this answer.