fake EF DBContext in Visual Basic.NET - vb.net

I found solution for faking DBContext in C#. Creating an Interface IDbContext. For production code I create a LifeDbContext that inherit from DbContext and implement IDbContext. For unit testing I create a class FakeDbContext that implements also IDbContext and fake the Datebase with Collections ... fine.
But now I have to do it with Visual Basic.NET. Because of I have to implicitly implement each member of the interface IDbContext I can not implement the members of DbContext base class.
In c# there is no need to explicit implement a member of an interface.
Any idea?
Here my code:
Public Interface IMyDbContext
Property Orders As IDbSet(Of Oders)
...
ReadOnly Property Database() As Database
Function SaveChanges() As Integer
ReadOnly Property Configuration As Infrastructure.DbContextConfiguration
End Interface
Public Class MyDbContext
Inherits DbContext
Implements IDbContext
Public Property Orders As IDbSet(Of Orders) Implements IMyDbContext.Oders
...
Public ReadOnly Property Database() As Database Implements ILimsDbContext.Database
Get
Return MyBase.Database
End Get
End Property
Public Function SaveChanges() As Integer Implements IMyDbContext.SaveChanges
Return MyBase.SaveChanges()
End Function
Public ReadOnly Property Configuration() As Infrastructure.DbContextConfiguration Implements IMyDbContext.Configuration
Get
Return MyBase.Configuration
End Get
End Property
End Class
What I don't like is the shadowing the already in DbContext implemented members in MyDbContext only for explicit implement the interface.

You can modify the t4 template to add your interfaces and implements clauses, but that would lock you into your customized t4 implementation. I did something along these lines in a post on adding property logging a while back. See if this post is helpful.

Related

Generic Collection of T for ICollection of DbEntities

The Situation-
Have EF database entities with collections of other database entities as navigation properties all of which are not exposed outside of the project. Each of these entities are nested in base classes that allow public read and protected set access to the Db entity's property values and are the classes the business layer will work with. So these base classes also need collections of their Db entity's navigation properties.
What I have now-
I am still working on how I want the data layer to interact with with the other layers that reference it. So I have been experimenting with creating collection classes that can be set equal to a collection of Db entities and create a collection of the base class that the Db entity is nested in. The collection is then exposed outside the class though an interface as well as the base class. The interface gives access to some custom methods of collection class like accepting DTOs and prebuilt quires but would hide any Add methods.
The Problem-
I would like to create a generic base class for the collections but cant seem to find a way. I have gotten close to something workable but it was ugly and confusing. Below is an outline of what I'm working with. The narrowing operators in the entity class work well. I would rather have widening operators and narrowing operators in the base class so I could keep the New method private for the base classes but I don't want to expose the actual database entities outside the Data Layer.
Interops Namespace referenced by all projects in solution-
Public Interface IGenericEntity
End Interface
Public Interface INavigationPropertyEntity : Inherits IGenericEntity
End Interface
Public Interface IDbEntityToExposedEntityCollection(Of TEntity As IGenericEntity)
'Used to hide Add method
End Interface
Public Interface IPublicEntity
ReadOnly Property NavProps As IDbEntityToExposedEntityCollection(Of INavigationPropertyEntity)
End Interface
Data Layer project-
-Database Entities
Friend Class DbEntity1
Public Shared Narrowing Operator CType(ByVal value As DbEntity1) As NavigationPropertyEntity
Return New NavigationPropertyEntity(value)
End Operator
End Class
Friend Class DbEntity2
Public Sub New()
NavigationPropertyDbEntities = New HashSet(Of DbEntity1)
End Sub
Public Property NavigationPropertyDbEntities As ICollection(Of DbEntity1)
Public Shared Narrowing Operator CType(ByVal value As DbEntity2) As PublicEntity
Return New PublicEntity(value)
End Operator
End Class
-Exposed Base Classes
Public Class NavigationPropertyEntity : Implements INavigationPropertyEntity
Private _value As DbEntity1
Friend Sub New(value As DbEntity1)
_value = value
End Sub
End Class
Public Class PublicEntity : Implements IPublicEntity
Dim _value As DbEntity2
Friend _NavProps As DbEntityToPublicEntityCollection(Of INavigationPropertyEntity, DbEntity1, NavigationPropertyEntity)
Public ReadOnly Property NavProps As IDbEntityToExposedEntityCollection(Of INavigationPropertyEntity) Implements IPublicEntity.NavProps
Get
Return _NavProps
End Get
End Property
Friend Sub New(value As DbEntity2)
_value = value
_NavProps = new DbEntityToPublicEntityCollection(Of INavigationPropertyEntity, DbEntity1, NavigationPropertyEntity)(_value.NavigationPropertyDbEntities)
End Sub
End Class
-Entity Specific Collection
Friend Class DbEntityToPublicEntityCollection(Of IEnt As INavigationPropertyEntity, DbEnt As DbEntity1, ExpEnt As NavigationPropertyEntity)
Inherits HashSet(Of IEnt)
Implements IDbEntityToExposedEntityCollection(Of IEnt)
Public Sub New(value As HashSet(Of DbEnt))
For Each ent In value
Dim exp As NavigationPropertyEntity = ent
Dim i As INavigationPropertyEntity = exp
MyBase.Add(i)
Next
End Sub
End Class
Additional Info Edit
The main issue is being able to have a generic collection declared something like,
Friend Class DbEntityToPublicEntityCollection(Of IEnt, DbEnt as class, ExpEnt As class)
because in the New sub ExpEnt cannot be converted to DbEnt and a TryCast will just result in a runtime error.
Like I said, I tried setting up classes that are inherited by the exposed and entity classes so a new method with a parameter for the exposed class could be set up but with trying to have the interfaces in there it got unmanageable pretty quick. Then again I have not worked much with making my own generic types before so I'm not sure if this is even a proper strategy.

Override variable from abstract class

I need to define a base class that contains the common implementation of logging in my application and create two specific classes LogA and LogB that will use the methods from the base class with a specific variable determining the logger to use.
Now I have the following code:
Public MustInherit Class BaseLog
Private Shared _Log As ILog 'This must be overridden in specific classes
Shared Sub WriteDebug (value As String)
End Sub
End Class
Public Class LogA
Inherits BaseLog
Private Shared _Log As ILog = LogManager.GetLogger ("aaaa")
End Class
How can I do this?
PS: I don't know how to format code on stackexchange mobile app.
You cannot override a field or a Shared member of your base class. Only a method or property that you declared Overridable can be overridden. You can a declare a method MustInherit to force a derived class to provide an implementation, you'd consider a GetLogger() function.
In a case like this, were you absolutely want to be sure that the client code hands you a valid logger, the more obvious solution is to add a constructor to your base class:
Public MustInherit Class BaseLog
Public Sub New(logger As ILog)
If logger is Nothing Then
Throw New ArgumentNullException("You must provide a logger")
End If
_Log = logger
End Sub
'' etc..
End Class
The client code is now forced to provide you with a valid ILog implementation, the only way they can create an instance of the derived class.
Without knowing your entire spec and what you're trying to achieve; I wonder if the singleton pattern get done what you need to get done.
Instead of LogB.WriteDebug("Oh noes!") you would have to do LogB.GetInstance().WriteDebug("Oh noes!"). Its not quite as nice, but when you're talking about the base class accessing a member set by a child class it might be the only way to go. This assumes you could use different logs in the same instance of your application.
If you just want to inject different loggers at runtime/startup for the duration (i.e. if you're running in production, development or unit testing), then you may want to look at dependency injection (such as Ninject), or some other form of IOC (inversion of control).
Clearly, this is a more complex problem than it first appears to be! However, it may be that we're stuck looking at it from the wrong angle.
You could have an instance property which is implemented in the derived class and returns the shared log variable:
Public MustInherit Class BaseLog
Public MustOverride ReadOnly Property _Log As ILog
Shared Sub WriteDebug(value As String)
End Sub
End Class
Public Class LogA
Inherits BaseLog
Private Shared log As ILog = LogManager.GetLogger("aaaa")
Public Overrides ReadOnly Property _Log As ILog
Get
Return log
End Get
End Property
End Class

Error when passing friend class as type from public class to friend base class

Disclaimer: I am fairly new to working with generics so I am not entirely sure if what I am trying to do even makes sense or is possible.
I have a bunch of user controls in a project. All of these user controls share a similar property so I want to move it into a base class. The only difference is the return type of the property.
I have three classes interacting in this scenario. The first class is a base type, which inherits from CompositeControl and will be inherited by other classes in my project:
Friend Class MyBaseClass(Of T As {New})
Inherits CompositeControl
Private _someProperty As T = Nothing
Protected ReadOnly Property SomeProperty As T
Get
// dumbed down for the sake of example
If _someProperty Is Nothing Then
_someProperty = New T()
End If
Return _someProperty
End Get
End Property
End Class
Then I have this control class, which inherits from MyBaseClass:
Public Class MyControlClass
Inherits MyBaseClass(Of MyReturnTypeClass)
// snip...
End Class
And finally MyReturnTypeClass which is what the base's SomeProperty should return:
Friend Class MyReturnTypeClass
Public Property AutoProperty1 As Boolean = False
Public Property AutoProperty2 As String = String.Empty
// etc
End Class
When I attempt to build the project, I get this error from MyControlClass:
Inconsistent accessibility: type argument 'MyReturnTypeClass' is less accessible than Class 'MyControlClass'.
I need MyControlClass to be Public so it can be consumed by other projects, and I also want the MyBaseClass and MyReturnTypeClass to be Friend so they cannot be seen/used by consumers. Am I just missing some special keyword somewhere or is this not possible?
You cannot inherit from a base class that is less accessible than the derived class. So for instance, this won't work:
Friend Class MyBase
End Class
Public Class MyDerived
Inherits MyBase ' Won't compile because MyBase is less accessible
End Class
Therefore, since in your example, MyBaseClass(T) has is a friend type, but you are trying to inherit from it into a public MyControlClass type. Therefore, even if you took generics and MyReturnTypeClass out of the "equation", it still wouldn't work.
However, with generics, even if no member of the public interface of the class actually uses the generic type, the type must still be at least as accessible as the derived type. For instance:
Public Class MyBase(Of T)
' T not actually used at all
End Class
Friend Class MyOtherType
End Class
Public Class MyDerived
Inherits MyBase(MyOtherType) ' Won't compile because MyOtherType is less accessible
End Class
The base class must be at least as accessible as the derived class. This is a language restriction (see here).
If you intend to avoid MyBaseClass being instantiated by consumers, consider marking it Public MustInherit instead of Friend. Hope this helps.

How to indicate that an Entity Framework object is implementing an interface? [duplicate]

This question already has answers here:
Partial Classes, LINQ, Interfaces and VB.NET
(2 answers)
Closed 2 years ago.
OK, I have to begin saying that I'm working with Visual Basic. The problem is that I have a Entity Framework object and I want to indicate that this object implements a interface, for example:
Public Interface ICatalog
Property created_at() As Date
Property id() As Long
End Interface
Those properties are allready in the object. In c# I've done this just by declaring a partial class of the object and indicates that implements that interface, but in basic is not working, I supouse that is because of the language sintaxis used to declare that a property is implementing some property of the interface, for example:
Public Property created_at() As Date Implements ICatalog.created_at
So is there any other way to accomplish this?
Take a look at this example.
Namespace MyAppDomain
Public Interface IFoo
Sub Bar()
End Interface
Public Interface IPerson
Function Gender() As String
End Interface
Public Class MyFooPerson : Implements IFoo, IPerson
Public Sub New()
End Sub
Public Sub Bar() Implements IFoo.Bar
End Sub
Public Function Gender() As String Implements IPerson.Gender
Return Nothing
End Function
End Class
End Namespace
You'll notice the MyFooPerson Class implements the IFoo Interface as well as the IPerson Interface. Each method then implements the corresponding Interface method.
Your example doesn't say whether or not the Class containing Public Property created_at() As Date Implements ICatalog.created_at is Implementing the ICatalog Interface.

In VB, How do you force an inherited class to use an attribute on the class?

I'm trying to force an inherited class to use a custom attribute. I'm creating a class library where the user who wants to create an item will do so, but be forced to add an attribute (or visual studio will automatically add the default attribute) to their inherited class. Here is what I'm hoping to achieve:
BaseClass.vb:
<CustomAttribute(10)> _
Public Class BaseClass
End Class
MyClass.vb:
<CustomAttribute(12)> _
Public Class MyClass
Inherits BaseClass
Public Sub New()
Mybase.New()
End Sub
End Class
So the thought is that much like when you mark a function as "MustOverride" and then the inherited class must override the function, I want the attribute to be "MustOverride" causing the inherited class to specify the value.
I've tried this, and it will work, but it would be much cleaner if I could use attributes:
BaseClass.vb:
Public MustInherit Class BaseClass
Public MustOverride ReadOnly Property CustomAttribute() As String
End Class
MyClass.vb:
Public Class MyClass
Inherits BaseClass
Public Sub New()
Mybase.New()
End Sub
Public Overrides ReadOnly Property CustomAttribute() As String
Get
Return "testing"
End Get
End Property
End Class
Thank you for any help you can provide.
Scott
Did you consider implementing an interface instead? I assume that you're using a base class as you want to provide some code in the base, if not then an Interface might be better depending on your other requirements:
Interface IBase
ReadOnly Property CustomAttribute() As String
End Interface
It's still very compact and when you type 'Implements IBase' in a new class Visual Studio will fill in the code for you.
There's no way in .NET to force a class to define an attribute at compile time. The best you'll be able to do is check at run-time whether the attribute was defined, and if not to throw an exception.