Closed vdurante closed 1 month ago
Hi,
Most likely, these methods do what they actually say.
Consider next pseudo-code:
#region fakes
public interface IA { }
public interface IB { }
public class AB : IA, IB { }
#endrigion
#region main
var sp1 = new SeviceCollection()
.Scan(x => x.FromAssemblyOf<AB>()
.AddClasses(classes => classes.AssignableTo<AB>())
.AsImplementedInterfaces()
.WithTransientLifetime())
.BuildServiceProvider();
var a = sp1.GetService<IA>(); // NOT NULL
var b = sp1.GetSerivce<IB>(); // NOT NULL
var ab= sp1.GetService<AB>(); // NULL
var sp2 = new SeviceCollection()
.Scan(x => x.FromAssemblyOf<AB>()
.AddClasses(classes => classes.AssignableTo<AB>())
.AsSelfWithInterfaces()
.WithTransientLifetime())
.BuildServiceProvider();
a = sp2.GetService<IA>(); // NOT NULL
b = sp2.GetSerivce<IB>(); // NOT NULL
ab= sp2.GetService<AB>(); // NOT NULL
#endregion
So, AsSelfWithInterfaces
means that every type that satisfies your predicate in AddClasses
will be registered as every interface that it implements + as itself. In other words, without the usages of Scrutor these can look like:
sp2 = new ServiceCollection()
.AddTransient<AB>()
.AddTransient<IA>(sp => sp.GetService<AB>())
.AddTransient<IB>(sp => sp.GetService<AB>())
.BuildServiceProvider();
a = sp2.GetService<IA>(); // NOT NULL
b = sp2.GetSerivce<IB>(); // NOT NULL
ab= sp2.GetService<AB>(); // NOT NULL
If I remember correctly there's a difference in instance reuse for longer lifetimes as well.
With AsImplementedInterfaces
, if you have singleton registrations for IA
and IB
where both are implemented by AB
, there will be two separate singletons - one for each registration.
But with AsSelfWithInterfaces
, the interface registrations will resolve the self-registered singleton, which means each interface registration will share one singleton instance.
Does that make sense?
Yeah, seems according to ScanShouldCreateSeparateRegistrationsPerInterface
and AsSelfWithInterfacesShouldForwardRegistrationsToClass
you remember correctly 😅
I think, from one point of view it does, from another no. Mostly because it works slightly differently in comparison with scanning in other DI containers. Since in past I worked mostly with Autofac, their AsImplementedInterfaces
works as your AsSelfWithInterfaces
(for sure, if we talk about types lifecycle), the same in the SimpleInjector, and if I correctly remember in the Windsor as well.
BTW, from Microsoft.Extensions.DependencyInejction
standpoint it makes sense.
Right. As I look at it, this is a limitation in the MS.Ext.DI container 😞
I am trying to understand how Scrutor works and I got quite confused regarding the differences between
AsSelfWithInterfaces
andAsImplementedInterfaces
. Besides the Self part, I noticedAsImplementedInterfaces
registers the interfaces directly to aImplementationType
, such asIRepository -> Repository
, but theAsSelfWithInterfaces
doesn't, since it registers the interfaces to the class using aImplementationFactory
.I understand de implementation differences between using a factory and a type, but I don't seem to understand the actual difference between both, specially regarding use cases. When should I use each?
Would appreciate if someone could help me out. Thanks!