I am getting an Invalid Cast Exception when doing Bar = IFoo but not when Bar = Foo even though that during run time the IFoo object is of Type Foo. The issue here is that the assemblies that work with the Bar Class should not not know about the Foo class. Foo is an DbEntity and Bar is what contains all the Business logic for Foo. I could use a Factory method in Bar but operators are just so convenient! Especially when getting Foo back out of Bar for database operations outside of the Bar class.
When trying to figure out what is going on I stumbled across this article, which is really interesting but does not offer any solutions to a situation like this. I don't know much about these kinds of odd runtime exceptions, so is there any way I can keep things separated out like I want them? Using a factory for Bar seems like the simplest method but I would like to know if there is a workaround in case I run into something like this again where that's not an option.
In Assembly referenced by all other Assemblies:
Namespace ISpace
Public Interface IFoo
End Interface
Public Interface IBar
ReadOnly Property SomeProperty As Integer
End Interface
End Namespace
In Assembly that should only be referenced by the Bar Class's Assembly
Namespace FooSpace
Public Class Foo : Implements ISpace.IFoo
Public SomeProperty As Integer
End Class
End Namespace
In Bar Class's Assembly
Namespace BarSpace
Public Class Bar : Implements ISpace.IBar
ReadOnly _value As FooSpace.Foo
Private Sub New(value As FooSpace.Foo)
_value = value
End Sub
Public ReadOnly Property SomeProperty As Integer Implements IBar.SomeProperty
Get
Return _value.SomeProperty
End Get
End Property
Public Shared Widening Operator CType(ByVal value As FooSpace.Foo) As Bar
Return New Bar(value)
End Operator
Public Shared Narrowing Operator CType(ByVal value As Bar) As FooSpace.Foo
Return value._value
End Operator
End Class
End Namespace
In an Assembly that should only reference the Bar Class's Assembly
Namespace TestSpace
Public Class FooBarTest
Public Shared Function GetMeBarFromFooFail(Foo As ISpace.IFoo) As IBar
Dim bor As BarSpace.Bar
bor = Foo 'Throws InvalidCastException
Return bor
End Function
Public Shared Function GetMeBarFromFooPass(foo As ISpace.IFoo) As IBar
Dim foofoo As FooSpace.Foo = foo
Dim bar As BarSpace.Bar
bar = foofoo 'No Exception
Return bar
End Function
End Class
End Namespace