I'm sure this has been asked before, but I can't seem to find the solution I'm looking for, despite a lengthy SO/Google search, so hoping you can answer my question.
For brevity, let's consider I have the following objects:
public interface ISectionView { }
public class SampleSectionView : ISectionView { }
public interface ISectionService<T> where T : ISectionView { }
public class SampleSectionService : ISectionService<SampleSectionView>
Now I have the following code in my controller:
ISectionView sectionType = new SampleSectionView(); // *** NOTE THE TYPE
var service = _serviceResolver.Resolve(sectionType);
And for the purpose of this, the _serviceResolver.Resolve method looks like this:
public ISectionService<V> Resolve<V>(V sectionViewModel)
where V : ISectionView
{
var sectionViewModelTypeName = sectionViewModel.GetType().Name;
// Ignore this, it's some AutoFac metadata resolution
var resolvableService = _services.FirstOrDefault(s => s.Matches(sectionViewModelTypeName));
if (resolvableService != null)
return resolvableService.Value as ISectionService<V>; // Upcast, as this is the actual type we want!
return null;
}
So, as we can see above, I created the sectionType variable in my controller as an ISectionView type, which the SampleSectionView implements. This is causing me a problem in the resolve method, as what this is actually doing (as I've checked this in the Immediate Window) is the following:
return resolvableService.Value as ISectionService<ISectionView>;
This is a problem, as my service wants to be converted to the following:
return resolvableService.Value as ISectionService<SampleSectionView>;
I know that I've passed a SampleSectionView object into this resolve method, but the casting based on the generic V type parameter is getting a bit lost.
So how can I get the cast to recognise the actual concrete type, rather than the interface type which it was created under?
For the record, I know I can do the following:
var sectionType = new SampleSectionView();
But this is a problem, as I need a Factory method to create me the ISectionView, so I know this is the type I'm passing into the Resolve. Yes, I can see why this is a problem, so what can be done to overcome this? I'd rather not have a switch/case statement to handle the casting, if at all possible.
Thank you
Answer
Thanks to all that commented. In the end, all I had to do was modify the ISectionService interface to the following:
public interface ISectionService<out T> where T : ISectionView { }
And this was enough.