I have a generic model:
public abstract class MyModel<T>
where T: MyBase, new()
{ ... }
and I have a specific model, where Foo inherits from MyBase:
public class MySpecificModel : MyModel<Foo>
{ ... }
and in my Razor template, I want to instantiate an instance of MySpecificModel:
@{
var test = new MySpecificModel();
}
If MyBase inherits from System.Windows.DependencyObject (because it happens to be a WPF ViewModel class that I need to reuse) I get an exception when the Razor template is compiled saying that I’m missing a reference to WindowsBase.dll, even though I have that reference in my project. I tried adding @using System.Windows to my template, but Razor won’t recognize the namespace at all.
To work around this issue, I changed the code as follows:
public abstract class MyModel
{
protected abstract MyBase myBase { get; }
...
}
public class MySpecificModel : MyModel
{
private Foo _myBase;
protected override MyBase myBase
{
get
{
if (_myBase == null)
_myBase = new Foo();
return _myBase;
}
}
...
}
Inside of MyModel I have to change any “new T()” to “myBase” in order to access the Foo object. This approach works perfectly, but it’s a lot more work for the MySpecificModel class, which I’m going to have many variations of for different sub-classes of MyBase.
So, why does the first approach fail while the second succeeds? It’s not just the use of generics, because if MyBase doesn’t inherit from a WindowsBase class there’s no problem. I think it has to do with where the Foo object is being constructed, and something Razor is doing to prevent the use of any WPF classes. But I can’t find any documentation about that.
ASP.NET generates a new anonymous assembly from the .aspx/.ascx/.master/.cshtml files that then references your web application’s assembly, the generated classes are stored in the
ASP.namespace. This assembly is generated at runtime when the first request is made to your web application.This new assembly only additionally references a few other assemblies (
System.Web.dll, etc) and not theSystem.Windows.xxxassemblies as you noticed.Because ASP.NET is generating a new assembly based on exposed types from
System.Windowsit needs to reference that assembly directly, which it won’t – whereas when it works with types that children of types derived from System.Windows types (i.e. your working example) it works because it isn’t interfacing with System.Windows directly.