Open MovGP0 opened 7 years ago
That's cool. with #95 we can inject controls by interface. But what's the xaml looks like? like this?
<Grid>
<DIContainer ResolveType="{x:Type IButton}"></DIContainer>
</Grid>
@h82258652 that is not DI, but the Service Locator Antipattern. I was talking about DI.
So basically:
public IMyService MyService { get; }
public Func<IAnotherService> AnotherServiceFactory { get; }
public MyControl(IMyService myService, Func<IAnotherService> anotherServiceFactory) : UserControl
{
MyService = myService;
AnotherServiceFactory = anotherServiceFactory;
}
@MovGP0 Oh, you mean DI in cs code. (what I though is DI in xaml code.) But DI in control constructor, the designer will be very complex. And if we have two or more constructors like your code, which one will be call?
There is the possibility to provide a default constructor for the Designer. This is how it worked in WinForms.
public partial class MyControl : UserControl
{
public IMyService MyService { get; }
public Func<IAnotherService> AnotherServiceFactory { get; }
public MyControl(IMyService myService, Func<IAnotherService> anotherServiceFactory)
{
MyService = myService;
AnotherServiceFactory = anotherServiceFactory;
}
// called by the designer
private MyControl()
{
MyService = Mock.Create<IMyService>();
AnotherServiceFactory = () => default(AnotherService);
}
// ...
}
Hard-coding your mocks in your control's code seems to be a bit of an anti-pattern as well. Moreover, this seems like an implementation detail of a platform supporting XAML Standard, rather than a function of the XAML standard itself.
Even with that said, this looks a bit backwards to me. Shouldn't this kind of code live inside a ViewModel class that the control binds to?
@lokitoth indeed. but then the ViewModel requires the DI.
What you currently end up with is to use DI on the VM and use a resource locator on the DataContext property of the XAML control. (That is unless you know a better method)
My intention is to get rid of the ressource locator altogether and inject the ViewModel into the constructor of the control.
It should be possible to do dependency injection on XAML controls. The DI mechanism should be registered on a per-assembly mechanism and may use the DI interfaces from ASP.NET Core. The DI should be overrideable in consuming assemblies for testing purposes.