Need help working with Abstract Classes and Generics - asp.net-mvc

i'm trying to build a class library for all of my mvc-5 projects. For that task i started with setting up some Abstract Classes for my DB Context and Indentity User like this
Public MustInherit Class ApplicationUserAbstract
Inherits IdentityUser
End Class
Public MustInherit Class DatabaseContextAbstract
Inherits DbContext
Public Property Users as DBSet(of ApplicationUserAbstract)
Sub New()
MyBase.New()
End Sub
Public Sub New(nameOrConnectionString As String)
MyBase.New(nameOrConnectionString)
End Sub
Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
MyBase.OnModelCreating(modelBuilder)
End Sub
End Class
I think i have to get another approach to set DatabaseContextAbstract.Users to the correct Class inherting something like T of ApplicationUserAbstract. Any sugestions for that? I have no clue how to pass this to Users except Using something like
Public MustInherit Class DatabaseContextAbstract(of T as ApplicationUserAbstract)
Inherits DbContext
Public Property Users as DBSet(of T)
End Class
My next question: how would i access the current Instance of DatabaseContextAbstract in my abstract class? All approaches of DatabaseContextAbstract(of DatabaseContextAbstract(... would be nonsense...
EDIT:
The basic idea behind this is to pack Tables and Functions in that abstract Classes. e.g. There are the same UserRight and Group Tables behind every ApplicationUser in all of my projects. But every project may have project specific tables additionally to the base tables. There is still just one Application user in every project.

I don't see a whole lot of point to what you're doing here. IdentityUser is already abstract. It's intended that you're going to create a concrete class that inherits from it. If you perhaps intended to have multiple different types of users that all shared some subset of custom properties, I could see maybe adding an abstract subclass of IdentityUser that implements those, but you're not doing that here. However, even if you did, the user for Identity is a bit of a special case. You can only have one user table, so inheritance must start from a concrete base class, regardless. For example, the following will work fine:
public class ApplicationUser : IdentityUser {}
public class FooUser : ApplicationUser {}
public class BarUser : ApplicationUser
This will not work:
public abstract class ApplicationUserAbstract : IdentityUser {}
public class FooUser : ApplicationUserAbstract {}
public class BarUser : ApplicationUserAbstract {}
In the second scenario, FooUser and BarUser would get separate tables, which is not supported by Identity. In the first scenario, single-table inheritance will be utilized so FooUser and BarUser will be in the same table as ApplicationUser, with a discriminator column.
When it comes to your context, again, there's limited utility in having a base abstract context class. The context is inherently tied to a database, and it doesn't make sense to have multiple context each interacting with its own unique database that are all virtually carbon-copies. Even if you're dealing with a multi-tenant app, you only need one context. The individualization of the databases would be handled via the connection string, not which context class is utilized.
Finally, if you're using Identity, your context should inherit from IdentityDbContext, not DbContext. Among other things IdentityDbContext already contains a DbSet for users, so the one you added is unnecessary.
Long and short, none of this code does anything for an application. It's pointless abstraction for the sake of abstraction.

Related

How do I define multiple EF DbContexts that share the same structure so they can use methods interchangeably?

I am using a single database design for 3 different SQL Server locations (production, backup, master). The design is simple, shown below for the production location:
Public Class ProductionDbContext
Inherits DbContext
Public Sub New()
MyBase.New("ProductionDbConnection")
End Sub
Public Sub New(connectionString As String)
MyBase.New(connectionString)
End Sub
Public Property Tables As DbSet(Of Table) 'Table includes a List(Of Topic)
Public Property Topics As DbSet(Of Topic) 'for direct access to Topics when needed
End Class
I have initially coded 3 separate contexts according to what's above, so:
Public Class ProductionDbContext
Public Class BackupDbContext
Public Class MasterDbContext
When I access these contexts for various operations, I'd like to do something simple like:
Dim prodDb As New ProductionDbContext
Dim backupDb As New BackupDbContext
Dim masterDb As New MasterDbContext
Dim topicsList As New List(Of Topic)
LoadData(topicsList, prodDb) or
LoadData(topicsList, backupDb) or
LoadData(topicsList, masterDb)
And then LoadData is defined as something like (but this doesn't work):
Public Sub LoadData(ByRef topicsList As List(Of Topic), localContext As Object)
Dim thisTopicTable = localContext.Tables.Include("Topics").Where(Function(x) x.Property = "something").SingleOrDefault()
If thisTopicTable IsNot Nothing Then
topicsList = thisTopicTable.Topics.ToList()
End If
End Sub
This doesn't work because localContext is not defined properly to have access to the EF methods like .Where and so on.
I know my current design attempt is not correct, but I don't have the experience yet to know how I should have designed things so that the 3 different databases/dbContexts can be treated as similar objects and I don't have to "repeat myself" throughout the code.
There may be a better way to setup the 3 separate databases that I should have used, and that would be great to know (implied question 1), but I would still like to understand more deeply how I use the idea of a Type Object when passing parameters so the object can be coded in the new method the same way as the object being passed in (question 2). I don't really do a lot of that type of coding; most of my code is very type structured.
I did try to design an intermediate Class that inherits DbContext that could then be inherited by my 3 Classes listed above, but I quickly `lost the pursuit curve' on that.

Are there problems with using inheritance from the domain layer for models in the storage layer?

Using EF 6 code first, relatively new to separation of concerns, DI, inheritance, etc. The classes below are simplified to focus on my question. I have an MVC Project for the presentation layer, a Class Library Project for the domain layer and a Class Library Project for SQL layer.
I designed the following model in the domain layer:
Public Class TaskList
<Key> Public Overridable Property TaskListID As Integer
Public Property TaskListOwner As String
Public Property Tasks As New List(Of TaskItem)
End Class
Public Class TaskItem
<Key> Public Overridable Property TaskId As Integer
Public Property TaskName As String
Public Property TaskDesc As String
Public Property TaskOwner As String
End Class
And this model in the SQL layer using inheritance from the domain:
Public Class SqlTaskList
Inherits TaskList
<Key> Public Overrides Property TaskListID As Integer
Function SqlToDomainTaskList() As TaskList
...
Return theDomainTaskList
End Function
End Class
Public Class SqlTaskItem
Inherits TaskItem
<Key> Public Overrides Property TaskId As Integer
Function SqlToDomainTaskItem(theSqlTaskItem) As TaskItem
...
Return theDomainTaskItem
End Function
End Class
Will I run into problems later on coding like this? It just seemed like using inheritance kept me from repeating myself when designing the SQL models (the real models are of course much larger), and also allows changes in the domain model to automatically propagate into the storage model. Did I get this right, wrong, partially right? Will I have problems later on doing it like this?
Regarding separation of concerns, wouldn't be OK for the SQL layer to be more tightly coupled with the domain since the SQL layer is always saving the domain objects?

What is the difference between ComponentModel.DataAnnotation and decorator pattern.?

I was implementing repository decorator pattern on my project as:
[Auditable]
public class Product
{
public int Id {get; set;}
public string Name {get; set;}
}
I got this idea from the following link.
https://efpatterns.codeplex.com/discussions/282699
But couldn't successfully implemented. Then I start learning about decorator pattern and DataAnnotation because the way Auditable attribute on Product entity is somewhat similar in DataAnnotation and decorator pattern. So my question is are they same thing.? If they are the same then how would I implement Auditable repository pattern (more on link) on my project.
That's not the decorator pattern as originally described by the Gang Of Four.
The decorator pattern is an inheritance technique to add functionality to existing classes. The pattern works by creating a set of subclasses which each provide a specific type of functionality on top of the base class.
Then you compose a combination by passing the existing instance as inner object to a subclass instance:
public class SecurityToken
public class ExpiringToken : SecurityToken;
public class RpcSecurityToken : SecurityToken;
So if you would like to have a token which is remote and will expire after an amount of time:
var token = new RpcSecurityToken(new ExpiringToken(new SecurityToken("sds")));
What you do is to just decorate a class with an attribute, which not is the same thing.
The decorator pattern is a mechanism of taking a base implementation of a given interface as extending its behavior without modification of original implementation.
Its similar to inheriting from a base class, however it has more flexibility. For example, a decorator class can be applied to any other class that implements the same interface, there is no restriction to only extending a single base class. They can also be chained together etc...
e.g
public interface IThing
{
void AMethod()
}
public abstract class ThingDecorator : IThing
{
private IThing inner;
public ThingDecorator(IThing inner)
{
this.inner = inner;
}
public virtual void AMethod()
{
this.inner.AMethod();
}
}
Inheriting from ThingDecorator and applying your own extension to the virtual AMethod will add behavior (decorate) the inner instance that is passed in. As the inner instance is coupled to an interface it can be any implementation of that interface.
In your example, you could inherit ThingDecorator as AuditThingDecorator, and override AMethod and include Audit features before you call the base.AMethod()
This is different to just applying an attribute to a class. I think you are trying to apply behavior with an attribute. Attributes can only apply behavior to the class if there is a container, or some other part of the system that can read them and actually apply given behavior. With DataAnnotations, there are other classes that read these attributes and apply behavior (for example, within ASP.NET MVC, the DefaultModelBinder use some of the attributes to provide validation when binding the model).
This is a AOP (apsect orientated programming) approach. One way to apply this (and a way I tend to use) is to use Castle.Core and create interceptors that can automatically implement interface methods or extend virtual methods and read attributes from the Methods/properties that are intercepting, and then apply behavior:
http://docs.castleproject.org/Tools.DynamicProxy-Introduction.ashx
They are both essentially proxies of a given type, however the Decorator pattern above is not dynamic, they are created within code, and the AOP approach can apply behavior at runtime.

How to design domain classes in Grails?

Given these functional requirements:
User Management
Administrator
Librarian
Borrower
*The users have the option of logging-in via OpenID.
Property Management
Book
Memorandum
Circular
License
Normally, I would implement these in Java as:
interface User {}
class Librarian implements User {}
class Administrator implements User {}
class Borrower implements User {}
class OpenID {} //all Users HAS AN OpenID attribute (NULL if non-openId login)
interface Property{}
class Book implements Property{}
class Memorandum implements Property{}
class Circular implements Property{}
class License implements Property{}
But our project will use Groovy & Grails, which I haven't experience using yet. My question is,
how should the domain classes be designed based on the requirements above? I can't use an interface, and it seems inheritance is not a good practice. My idea is to use composition, though I'm quite bothered by the database tables that would be generated. What are the best practices in this situation?
Well first of all lets correct it, you can use inheritance in this case. You just need to change the convention of has a relationship to is a relationship.
Few factors to keep note of:
1. Grails works on convention over configuration.
2. You can use GORM which wraps the persistence layer and creates an Object Mapping for the underlying persistence layer with the help of Hibernate.
As per your functional requirement:-
If you do not want to have the User as part of persistence you can have an abstract class User which can hold the common properties of the User including the openId attribute. It has to be placed in src\groovy directory as per convention (since the base class is abstract, dependency injection will be defied)
The same goes for Property. Abstract Property class in src\groovy.
Now coming to the business models, extend each of the concrete entities (domain classes) from the abstract parent.
Summary:-
Create grails app
Under src\groovy(for example, I am considering a basic structure):
User.groovy:-
abstract class User{
String name
String emailId
OpenID openId
}
Property.groovy:-
abstract class Property{
String propertyName
}
Under grails-app/domain:
Librariran.groovy:-
class Librarian extends User{
//Attributes specific to Librariran
static constraints = {
}
static mapping = {
}
}
Book.groovy:-
class Book extends Property{
//Attributes specific to Book
static constraints = {
}
static mapping = {
}
}
So on and so forth. Groovy objects under grails-app/domain are considered concrete entities by Grails convention. More information you can obviously find here. You can also use composition if you come across scenarios, in fact I already mentioned that in User having OpenId.
Note:- This is context to latest version of Grails (> 2.x)

In asp.net-mvc, is there a more elegant way using IOC to inject mutiple repositories into a controller?

I have an asp.net-mvc website and i am using ninject for IOC and nhibernate for my ORM mapping
Here is my IOC binding code:
internal class ServiceModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IIntKeyedRepository<>)).To(typeof(Repository<>)).InRequestScope();
}
}
and here is an example of how I am doing IOC into my controller code:
public FAQController(IIntKeyedRepository<FAQ> faqRepository, IUnitOfWork unitOfWork)
{
_faqRepository = faqRepository;
_unitOfWork = unitOfWork;
}
The issue is that up until now, each controller had a single table that it was pointing to so i only needed on repository class passed into it...
Now, I have a number of tables and classes that are all just have 2 fields:
Id
Name
for each of these classes, i simply inherit from a base class called:
BaseModel
which is just:
public class BaseModel
{
public virtual string Name { get; set; }
public virtual int Id { get; set; }
}
I want to have one:
StaticDataController
class that can do all of the CRUD for every class that simply inherits from BaseModel (with no extra fields)
The dumb simple way would be to do this:
private readonly IIntKeyedRepository<Object1> _object1Repository;
private readonly IIntKeyedRepository<Object2> _object2Repository;
private readonly IIntKeyedRepository<Object3> _object3Repository;
private readonly IIntKeyedRepository<Object4> _object4Repository;
private readonly IIntKeyedRepository<Object5> _object5Repository;
public StaticDataController(IIntKeyedRepository<Object1> obj1Repository, IIntKeyedRepository<Object2> obj2Repository, IIntKeyedRepository<Object3> obj3Repository, IIntKeyedRepository<Object4> obj4Repository, IIntKeyedRepository<Object5> obj5Repository)
{
_obj1Repository= obj1Repository;
_obj2Repository= obj2Repository;
_obj3Repository= obj3Repository;
_obj4Repository= obj4Repository;
_obj5Repository= obj5Repository;
}
Since I am passing the table in as a parameter to my methods, I would have to have some switch statement in my controller to get the right repository class based on the string of the parameter.
I assume there must be a much more elegant way to support what I am trying to do so I wanted to see if there is any best practice here (controller inheritance, reflection, etc.)?
If you need to do this it means that your controller does too many things and a strong indication that it requires a service layer. In this case I deport those repositories into the service layer. So my controller takes a service instead of multiple repositories:
private readonly IStatisticDataService _service;
public StaticDataController(IStatisticDataService service)
{
_service = service;
}
The service has business that could be composed of multiple atomic repository CRUD methods.
I know that you might say: yes, but now I have to inject all those repositories into the implementation of the IStatisticDataService interface. Yes, but it would make more sense to aggregate those atomic CRUD operations into the service layer rather than the controller.
But if need 5 or more repositories in order to perform a some business operations, maybe you have to rethink your domain architecture. Probably you could use composition in your domain models and define relations between them in order to reduce the number of repositories. It's difficult to provide more concrete advice without knowing the specifics of your domain.
Now, I have a number of tables and classes that are all just have 2 fields:
Great, make them derive all from the same base domain model and have a single repository to serve them. You could use descriminator columns, etc...
Darin is absolutely right. I'd just like to add though, if you're using MVC 3, you should be using the Ninject.MVC3 nuget package rather than creating your own Service Module.
As Mark Seemann mentioned: "It's quite OK, but once you feel that the Controller becomes too cluttered, you can refactor its dependencies to an Aggregate Service."
Look at: BestPractices: Is it acceptable to use more than one repository in a MVC-Controller?

Resources