Nhibernate and inheriting mapping-by-code - vb.net

I have two classes, one inheriting from the other. The first shows a summary view of data (4+ columns) and the child shows a detail view (40+ columns). Both classes are accessing the same table and share the same columns being accessed.
Can my child class inherit from the parent class so I only have to change mappings in one place? I'd rather not have duplicate code running rampant.
E.g.:
Public Class Parent
Public Overridable Property MyProp As String
Public Overridable Property MyProp2 As String
End Class
Public Class Child : Inherits Parent
Public Overridable Property MyProp3 As String
End Class
I want to do something like this:
Public Class ParentMapping
Inherits ClassMapping(Of Parent)
Public Sub New()
Me.Property(Function(x) x.MyProp, Sub(y) y.column("MyProp"))
Me.Property(Function(x) x.MyProp2, Sub(y) y.column("MyProp2"))
End Sub
End Class
Public Class ChildMapping
Inherits SubClassMapping(of Child)
Public Sub New()
' I want to be able to inherit the mappings of the parent here.
MyBase.New()
Me.Property(Function(x) x.MyProp3, Sub(y) y.column("MyProp3"))
End Sub
End Class

If you want the Child to be a subclass of parent in db also, you'll need a discriminator column.
If you just want to reuse code then share a mapping base class
public abstract class ParentChildMapping<T> : ClassMapping<T> where T : Parent
{
public ParentChildMapping()
{
// map shared properties here
}
}
public class ParentMapping : ParentChildMapping<Parent>
{
}
public class ChildMapping : ParentChildMapping<Child>
{
public ChildMapping()
{
// map additional properties here
}
}

Related

VB.Net clone hierarchy where parent has reference to child and vice versa -> circular reference

This is the situation:
Class A
Implements ICloneable
Public Property Children As List(Of Child)
Public Function Clone() As Object Implements ICloneable.Clone
Return New A With {
.Children = Children.Select(Function(c) DirectCast(c.Clone(), Child)).ToList()
}
End Function
End Class
Class Child
Implements ICloneable
Public Property Parent As A
Public Function Clone() As Object Implements ICloneable.Clone
Return New Child With {
.Parent = DirectCast(Parent.Clone(), A)
}
End Function
End Class
The actual object is more complex, having several levels.
I'm not sure how to solve this because, at the moment, whenever you call Clone on the parent A class, you will end up with a circular reference.
How can I avoid this situation? Should I create my own Clone function and pass along a parameter?
The simplest solution is to just have the Child class not clone the Parent property at all. When a Child clones itself, it could either leave the Parent property the same, or just leave it null. For instance:
Class Child
Implements ICloneable
Public Property Parent as A
Public Function Clone() As Object Implements ICloneable.Clone
Return New Child() With { .Parent = Me.Parent }
End Function
End Class
Then, when the parent A class clones itself, it could set the Parent property of all the cloned children, like this:
Class A
Implements ICloneable
Public Property Children As List(Of Child)
Public Function Clone() As Object Implements ICloneable.Clone
Return New A() With
{
.Children = Me.Children.Select(
Function(c)
Dim result As Child = DirectCast(c.Clone(), Child))
result.Parent = Me
Return result
End Function).ToList()
}
End Function
End Class
Alternatively, as you suggested, you could make your own Clone method which takes the parent object as a parameter:
Class Child
Public Property Parent as A
Public Function Clone(parent As A) As Object
Return New Child() With { .Parent = parent }
End Function
End Class
It won't implement ICloneable, but as long as you don't need it to be interchangeable with other types of ICloneable objects, then that won't matter. Similarly, you could just overload your constructor:
Class Child
Public Property Parent as A
Public Sub New()
End Sub
Public Sub New(childToClone As Child, parent As A)
' Copy other properties from given child to clone
Me.Parent = parent
End Sub
End Class

Implementing an Interface with Child Classes

I have the following interfaces:
Interface IViewModel
...
End Interface
Interface ISpecialViewModel
Inherits IViewModel
...
End Interface
Interface IView
WriteOnly Property MyViewModel As IViewModel
End Interface
Following are my classes:
Class VerySpecialViewModel
implements ISpecialViewModel
...
End Class
Class View
Implements IView
Public WriteOnly Property MyViewModel As VerySpecialViewModel Implements IView.MyViewModel
...
End Property
End Class
It tells me that 'MyViewModel' cannot implement 'MyViewModel' because there is no matching property on interface 'IView'.
Public Interface ISomething
WriteOnly Property Prop As IParent
End Interface
That interface declaration isn't satisfied by your class implementation. Consider following situation:
There is another interface called IChild2:
Public Interface IChild2
Inherits IParent
...
End Interface
According to ISomething interface you should be able to assign instance of class implementing IChild2 into Thing.Prop, because it inherits IParent.But you can't, because Thing.Prop property is of IChild type and IChild2 does not inherits IChild
Update
What about that solution:
Class ThingBase
Implements ISomething
Public WriteOnly Property Prop As IParent Implements ISomething.Prop
Set(value As IParent)
End Set
End Property
End Class
Class Thing
Inherits ThingBase
Public Overloads WriteOnly Property Prop As IChild
Set(value As IChild)
MyBase.Prop = value
End Set
End Property
End Class
Update2
Interface IView(Of T As IViewModel)
WriteOnly Property MyViewModel As T
End Interface
Class VerySpecialViewModel
Implements ISpecialViewModel
End Class
Class View
Implements IView(Of ISpecialViewModel)
Public WriteOnly Property MyViewModel As ISpecialViewModel Implements IView(Of ISpecialViewModel).MyViewModel
Set(value As ISpecialViewModel)
End Set
End Property
End Class
or
Class View
Implements IView(Of VerySpecialViewModel)
Public WriteOnly Property MyViewModel As VerySpecialViewModel Implements IView(Of VerySpecialViewModel).MyViewModel
Set(value As VerySpecialViewModel)
End Set
End Property
End Class

VB.Net and access via a variable of an interface type

How do I make the properties of a class available in an inheriting class, for a variable that is declared to be the type of one of the interfaces implemented by that class?
What I have done so far is to create an abstract class MyAbstract with the keyword MustInherit and in the inheriting class MyInheritingClass I have added inherits and then the name of the abstract class. Now this is all fine, but in my inheriting class, if I create an interface on that class MyInterface and use that interface elsewhere in my code, I have then found that I cannot see the properties from my abstract class, on the variable declared with that interface.
Am I doing something wrong here, or is there something else that I need to do?
An example would be as follows:
Public MustInherit Class MyAbstract
Private _myString as String
Public Property CommonString as String
Get
Return _myString
End Get
Set (value as String)
_myString = value
End Set
End Property
End Class
Public Class MyInheritingClass
Inherits MyAbstract
Implements MyInterface
Sub MySub(myParameter As MyInterface)
myParameter.CommonString = "abc" ' compiler error - CommonString is not a member of MyInterface.
End Sub
'Other properties and methods go here!'
End Class
So, this is what I am doing, but when I use MyInterface, I cannot see the properties of my Abstract Class!
Unless I've completely misunderstood your question, I'm not sure why you are confused by this behavior. Not only is that how it should work, but that is also how it works in c#. For instance:
class Program
{
private abstract class MyAbstract
{
private string _myString;
public string CommonString
{
get { return _myString; }
set { _myString = value; }
}
}
private interface MyInterface
{
string UncommonString { get; set; }
}
private class MyInheritedClass : MyAbstract, MyInterface
{
private string _uncommonString;
public string UncommonString
{
get { return _uncommonString; }
set { _uncommonString = value; }
}
}
static void Main(string[] args)
{
MyInterface test = new MyInheritedClass();
string compile = test.UncommonString;
string doesntCompile = test.CommonString; // This line fails to compile
}
}
When you access an object through any interface or base class, you will only ever have access to the members that are exposed by that interface or base class. If you need to access a member of MyAbstract, you need to cast the object as either MyAbstract or MyInheritedClass. This is true in both languages.

Accessible from only one class

I have a class and a method in it. The method's access modifier is now private but it can be changed. Now i just want the method to be seen only one another class.
the other class and my class are in same directory by the way.
The only way to allow a method in a class to be available to only one other class is to use a nested private class.
public class Enclosing
{
private class InnerClass
{
public void MyMethodThatCanOnlyBeUsedByEnclosingClass()
{}
}
}

Private or Protected Set for a MustOverride Property

I'd like to have a Private or Protected "Setter" for a property that also happens to be an abstract (MustOverride). I'm porting some code from C# to VB and in C# this is pretty straight forward. In VB not so much (for me anyway).
Some code...
In C#...
public abstract class BaseClassWithAnAbstractProperty
{
public abstract int AnAbstractIntegerProperty { get; protected set; }
}
public class Foo : BaseClassWithAnAbstractProperty
{
private int _anAbstractIntegerPropertyField = 0;
public override int AnAbstractIntegerProperty
{
get { return _anAbstractIntegerPropertyField; }
protected set { _anAbstractIntegerPropertyField = value; }
}
}
In VB...
Public MustInherit Class BaseClassWithAnAbstractProperty
Public MustOverride Property AnAbstractIntegerProperty() As Integer
End Class
Public Class Foo
Inherits BaseClassWithAnAbstractProperty
Private _anAbstractIntegerPropertyField As Integer
Public Overrides Property AnAbstractIntegerProperty As Integer
Get
Return _anAbstractIntegerPropertyField
End Get
Protected Set(ByVal value As Integer)
_anAbstractIntegerPropertyField = value
End Set
End Property
End Class
The issue seems to be the inability to flesh-out the Get/Set specifics in the declaration.
Am I chasing a ghost?
For the record, the closest VB translation would give you:
Public MustInherit Class BaseClassWithAnAbstractProperty
Public ReadOnly MustOverride Property AnAbstractIntegerProperty() As Integer
End Class
This might work, but as I found out, VB doesn't support this for Interfaces, at least