Repository Pattern with Dynamic Connection String Based on Database Values - c#

I have been looking into updating an existing codebase to better follow design patterns, principals, handle unit testing, separating concerns, etc. I am new to implementing a lot of these concepts so I am still doing a lot of research and trying to see how they could be implemented in the current codebase.
Currently each business entity has its own vb file. Within that vb file contains the entity, entity collection, and entity dalc classes for that entity. If you want to perform a database operation on the entity you would do so by calling Enity.Save, Entity.Delete, etc. These methods on the entity class would create the entity dalc object and then call the Save, Delete, etc. method on the entity dalc object. The dalc would then call a Save, Delete, etc. stored procedure through a SqlHelper class that handles the low level stuff.
Each entity class requires a Location object to be passed into it's constructor. This object is used to know what database the user is logged into as well as create the appropriate connection string to the database. The databases all have the same schema; they just have different names and can live on different SQL instances. Basically each client has their own database and the Location object hits up a shared database to find out what SQL instance the client needs to connect to based on the client's name which is stored in a cookie.
I have been looking into a more Model/Repository/Service approach but the Location object is throwing me off, especially since it too needs to access the database to get the information it needs to create the correct connection string. The repository objects need the connection string, but all of the examples I have seen have it hardcoded in the class. I am thinking the repository objects will need to take in an interface of the Location object but I'm not sure if the MVC project would do that directly or pass it into the service objects and they would handle it. At what point does the Location object get created, since it too needs to access the database in order for it to create the connection string, how does it get created?
I am also not clear on how the MVC project would interact with the Service and Repository layers. It seems like everything should run through the service objects, but for testing you would want them to take in an interface for the repository. Doing this would mean the MVC project would need to pass in the repository object, but it doesn't seem like the MVC project should know about the repository objects. However, if you are just doing basic CRUD it seems like it would be simpler to have the MVC project directly call those methods on the repository objects instead of running them through a service object.
Here is an example of what I am currently looking into. The plan is to use ADO.NET and SQL Server for now but possibly switch to an ORM or even a different SQL backend in the future. I am hoping the Model/Repository/Service approach will make it easy to make those changes in the future so if not feel free to offer advice on that as well.
Project.Model
public class Person
{
public int Id;
public string Name;
}
Project.Repository
public class PersonRepository
{
public Person FindById(int id)
{
// Connect to the database based on the Location's connection string
}
}
Project.Service
public class PersonService
{
private IPersonRepository _personRepository;
// Should this even take in the repository object?
public PersonService(IPersonRepository personRepository)
{
_personRepository = personRepository;
}
// Should the MVC project call this directly on the repository object?
public Person FindById(int id)
{
return _personRepository.FindById(id);
}
}
Project.MCV
// I think the Location object needs to come from here, as the client name is
// in the cookie. I'm not sure how the controllers should interact with the
// service and repository classes.

I second #Christian's advice. Using an ORM will greatly simplify your interactions with the underlaying data store; and NHibernate is a great choice.
However, in your example, the common way to interact with the data layer from the presentation (aka ASP.NET MVC project) is to inject the service as a dependency for your controller.
There are several ways to do this, the simplest, most straightforward is to use a dependency injection framework (like Unity) to instantiate your services as you specify in the controller's constructor,
public class PersonController : Controller
{
private readonly IPersonService personService;
public PersonController(IPersonService personService)
{
this.personService = personService;
}
}
Another way is to implement your own ControllerFactory implementation and inject the required services as needed. It is a lot more work, but if you have the time, you can lear a ton about the over all flow of the ASP.NET MVC routing flow and a bit of DI itself.
In a DI framework you (mostly) register interfaces with concrete classes implementations, basically saying that when an instance of IPersonRepository is required, use a new instance of PersonRepositoryImpl. With these registration rules in place, the DI framework will then recursively instantiate each dependency as it appears in the class constructor.*
In other words, when you request an instance of PersonController, the DI framework will then try to create an instance of type PersonController; when it sees that the constructor required an argument of type IPersonService, it first tries to instantiate one based on the same rules. Thus, the process starts again until all dependencies have been resolved and injected into the constructor for PersonController,
resolve PersonController
-> construct PersonController(IPersonService personService)
-> resolve IPersonService with PersonService
-> construct PersonService(IPersonRepository personRepository)
-> resolve IPersonRepository with PersonRepository
-> construct PersonRepository() <- this one has no dependencies
And back up the stack until a new instance of PersonController is returned.
*For this to work you must have only one public constructor for the given class, where each argument is a dependency that needs to be resolved (your examples nailed this down). If the type of the dependency is not registered with the framework, the resolution will fail. If there are multiple public constructors, the resolution will also fail (there is no sure way to determine which one to use), unless you register which constructor should be used (usually using attributes, but it depends on the DI framework in place). Some DI frameworks (like Unity) might allow you to have no constructor at all (which defaults to an empty, parameterless constructor) and have dependencies as public properties marked with a dependency attribute. I suggest not to use this method as it provides no way of knowing from a consumer class what dependencies the class needs (without using Reflection to inspect all properties and see which ones are marked as dependencies), which will in turn cause a myriad of NullReferenceExceptions.

Related

Moq a data source for a web service

I'm working on a fairly complex multi-tiered application and I'd like to mock the data source for one of the layers as it's very difficult for it to get to the database much of the time. (Some of it doesn't even exist yet.)
What I'd like to be able to do is set a flag in one of the web services to have it use the mocked data source instead of the database connection. I'm just going to put data in xml files. I've successfully used moq in unit tests but it seems I can't make that mental leap to where I can replace the injected database with the mock at run time.
The Stack:
VS 2013
.Net 4.5.1
Ninject
Entity Framework 5?
SQL Server 2012
Several attached databases that are called via stored procedures in SQL Server
Moq 2.x
WCF
Web API 2
Rather than set a flag, why not use and interface and pass that in? E.g. IDataSource.
Your web service, for example, takes an IDataSource as part of its construction.
Then, your moq can implement the interface and you can pass that in, rather than a real implementation of IDataSource. Similarly, your real database would implement the interface, too...
public class MoqDataSource : IDataSource
{
...
}
public class RealDatabase : IDataSource
{
...
}
As for replacing the real data source, at run time, you could use some kind of factory class that returns an IDataSource, and then use any number of methods to decide what the factory returns.
E.g. the factory reads some config file, and depending on what you've set there, it either returns a real data source, or the moq...
public class DataSourceFactory
{
public static IDataSource CreateDataSource()
{
if (/* are we using real data source */)
{
return new RealDatabase();
}
else
{
return new MoqDataSource();
}
}
}
It doesn't matter whether you call it a factory or something else... it's just one way of encapsulating the creation of an IDataSource. Only the factory class needs to be concerned with what type of IDataSource you want to create, the rest of the application doesn't have to worry about it.
IMHO, the easiest way might be to use a file that you can set the dependency information into. This way, you can switch between the Moq and the actual data source with a simple xml file change (could even drive that using different build targets, etc. but that's going beyond the scope of your original question).
In order to integrate an xml file for Ninject to consume, you will need an extension:
https://github.com/ninject/ninject.extensions.xml
HTH...

.NET Desktop Application (Service) 3-tier application

I have just started to design a .NET library that is going to be used by either an application or a service (but this should not matter with 3-tier architecture?) and I'm struggling to find a proper separation of concerns and at the same time link DAL with BL in a proper way.
I was looking for tutorials, etc., but they all point to ASP.NET and Entity Framework, but I'd like to use ADO.NET (DataSets, DataTables) to build a library for desktop application / windows service usage.
Would anyone point me to a right direction by providing any sample/example implenentation or a tutorial/guide??
#EDIT
I was thinking about something like that:
DbManager - abstract class
XDbManager - X being a provider, SQL, etc. deriving from DBManager, being a singleton class (I'd prefer static, but these can't implement interface or derive from classes)
DbConnection - an object returned by DbManager method, containing methods for querying
BaseDbo - abstract class for Database Object
XDbo - X being the name of DBO, using DbManager => DbConnection to query (save, retrieve, retrieve sets, save sets? this is where I'm a bit confused, I need few persistent DataSets to save, update, retrieve data from tables - should they be implemented as Database Objects deriving from DataSets?)
BaseBo - abstract class for Business Object
XBo - business object class to handle and process data, etc.
Saying above I can't find a proper way to "link" both layers.
I also need to make use of SOAP web service in here, should that be implemented on business layer? Or should I introduce a new sub-layer?
If your application is properly designed, using EF or ADO.Net shouldn't matter much: that's the point of the DAL abstraction. I.e. you'll still have a method such as:
public IEnumerable<User> GetAllUsers()
{
....
}
that will returns all of your users. How it's implemented (i.e. Entity Framework or ADO.Net) is not important. The only difference is that your DAL won't be able to return IQueryable<T> (i.e. deferred execution won't work, or you'll need another abstraction layer on top of ADO.Net).
Same as for ASP.Net vs Desktop application: this shouldn't vary much either. You should use WCF services instead of ASP.Net MVC controllers. Instead of directly calling the BL from your controller, you would call a method of a WCF generated client proxy.
Everything that you could read about 3-tier application should apply for your use case too.

Ramifications of using DBContext with Dependency Injection

I'm still kind of new to using dependency injection to manage my DBContext in an ASP.NET MVC application I'm writing.
I'm attempting to follow the approach outlined in the article Managing Entity Framework DbContext Lifetime in ASP.NET MVC. Basically, this approach says to use Ninject and dependency injection and to add my DBContext as a parameter to the constructor in my controllers.
Further, I am implementing this in a base controller, or which all my controller classes will be derived.
This is working, but I'm hitting on the following issues.
This approach requires that every derived controller class also implements a constructor that accepts any arguments requires by my controller base class. Not only does this seem like a lot of extra typing that I must remember to add to any new derived class, but it also means that if I change the data passed to the constructor then I must modify the constructor in every derived controller class.
This gives me a DBContext for all my controller classes. But what about other classes in my model that need the DBContext? Should I need to manually pass the instance to the DBContext to all these classes? Or is there a way to use DI for each of these classes to get their own copy of the DBContext?
This approach requires that every derived controller class also
implements a constructor that accepts any arguments requires by my
controller base class. Not only does this seem like a lot of extra
typing that I must remember to add to any new derived class, but it
also means that if I change the data passed to the constructor then I
must modify the constructor in every derived controller class.
This is one of the approach (Heavy Controller) that you may choose to use EF into your application, IMO its not the cleanest approach. And you correctly noticed the drawbacks your self.
If we relate this approach to design principle, it breaks Single Responsibility Principle as controller is expected to do more (fetch or update DB) than just collecting the data and return the appropriate view with data. And how about business rules, would controller apply it, if you need to send an email, would controller does that as well. You ought to have another layer of business/service classes that are specifically designed for a set of requirement e.g. EmailHelper would send emails.
It also breaks Open Close Principle as you need to change the constructors every time you change the input parameter.
This gives me a DBContext for all my controller classes. But what
about other classes in my model that need the DBContext? Should I need
to manually pass the instance to the DBContext to all these classes?
As far as dependency injection is concerned one of the goal is, to inject the dependency where it is needed directly. If you have a model class that needs DbContext, you should inject it in your model class constructor (most DI framework support property injection as well but constructor remains favourite approach).
With DI Framework, you will configure the dependencies at one place (application initialization code) and then each class that need a dependency just accept it in constructor.
DI Container can be compared to a dictionary where key is interface and the value is a cooked object. Once its setup, you can anytime ask for any object by using the right key through out your application.
Or is there a way to use DI for each of these classes to get their own
copy of the DBContext?
The DI framework supports different ways of instantiation to allow controlling the lifetime of the instance. Typically, per request, per thread and singleton. More information here. If you want each controller to get a copy of DbContext, you can use per request configuration when you set up DbContext instantiation.
Alternate Solution:
Most of my MVC applications, I have had a service layer (set of classes that apply business rule). Each of these classes were injected with DbContext (not exactly a DbContext but IDataContext). The controllers were injected with the service class that they need to retrieve or update the data.
Have abstracted the DbContext behind IDataContext, I could setup a stub data context in my test or tomorrow if I want to switch from EF to NHibernate or something more smart DI Framework, i will just have to implement IDataContext and change the dependency initialization code.
Hope this helps.

Few questions regarding BLL and DAL in my first 3-tier Winform Application

I am trying to create 3-tier winform application. Since this is my first attempt of 3-tier design, I got stuck and have few questions.
The application will support attaching multiple sqlite db files.
So I created class like this
public class Database
{
public string Name { get; set; }
public string FilePath { get; set; }
public bool isAttached { get; private set; }
}
Now I want to have collection of those objects.
Should I create another class like DatabaseList below or is enough to just create a List
public class DatabaseList : List<Database>
{
...
vs
List<Database> myDatabases;
What should be created in Form1.cs?
For example I assume the collection above should be created in BusinessLayer and not in Form1.cs and only BusinessLayer class is created in Form1.cs. Is this correct?
Where to put Attach Method?
The method would be like this:
public void AttachDB(Database db)
{
MySqliteHelper.Attach(db.Name, db.FilePath);
this.Add(db);
}
Do I put the method in DatabaseList class (if this is the way to create collection) or should it be in BusinessLayer?
How to make the Attach method to support additional relational databases like MS SQL Compact Edition which also resides in a single file
I was thinknig of creating another general database helper class with same methods as MySqliteHelper and the AttachDB method would call that instead. Something like
MyDBHelper.Attach(db.Name, db.FilePath);
Or is this where Dependency Injections like Ninject can be helpful? I never used that before and all I am recalling from Ninject is a samurai having different weapons so it seems to me to be kinda similar to my problem having different specific database classes.
I'm going to tackle this question in parts because it covers a lot of ground.
What qualifies as a 3-tier architecture?
A 3-tier (or n-tier, tiered) architecture is basically any design where the interface doesn't directly communicate with the database, no matter how thin the actual tiers are. You could create a single class with functions to get and save data, and it would still qualify as a 3-tier architecture. That being said, what I'm going to explain below is probably the most common implementation of a 3-tier architecture.
Layer vs. Tier: What's the difference?
To understand the 3-tier architecture, it's important to first make a distinction between a layer and a tier. An application can have many physical layers and still contain only three logical tiers. If a picture really is worth a million words, the diagram below should clear that up for you.
In the diagram above, the Business/Middle Tier is comprised of business logic, business objects, and data access objects. The purpose of this tier is to serve the middle man between the user interface and the database.
The Data Access Layer (DAL)
The data access layer is comprised of a data access component (see below) and one or more data access objects. Depending on the need, the data acess objects are usually set up one of two ways:
One Data Access Object for each Business Object
One Data Access Object shared by many Business Objects
It sounds like you're going to be dealing with several databases, so it would probably make sense to go with the one-to-one option. Doing it this way you'll have the flexibility to specify which database/connection corresponds to which business object.
Data Access Component
Your data access component should be a very generic class containing only the bare-bones methods needed to connect and interact with a database. In the diagram above, that component is represented by the dbConnection class.
Questions & Answers
What should be created in Form1.cs?
The only thing the front end deals with are the business objects and the business logic. Sometimes it's not that black and white, but that's the idea.
Where to put Attach Method?
Instead of an Attach method, pass a connection string into your data access component. A connection string can be used to attach and/or connect to pretty much any database.
How to make the Attach method to support additional relational databases like MS SQL Compact Edition which also resides in a single file?
See above.
Should I create another class like DatabaseList below or is enough to just create a List?
Honestly, this is up to you and doesn't affect the validity of the 3-tier architecture. You know the specific requirements that you're trying to meet, so do it if it makes sense. Give consideration to how your Data Access Object(s) will interact with this class though, because you will need to expose the methods for executing queries and non-queries on whatever database is selected from the list.
What you lack is thinking in terms of objects and their responsibility.
What object is responsible for creating instances of your database descriptions? Should it be Form1?
The OOP tells you that if you have such doubts you can follow the Pure Fabrication principle and just create another class to be responsible for this. This is just as simple.
So you can create a class, let call it DatabaseManager, put your list of databases there plus the Attach method. You probably also want this manager to be an ambient class (the same instance shared among other classes) so you can build a Singleton out of it (but this is not necessary).
DI containers could probably help you to organize services and manage their lifetime but I recommend you start with a good book on this before you misuse the idea. Mark Seemann's "Dependency Injection in .NET" is fine.
You need to think in terms of modularity and abstraction. See you have multiple entities to be passed across layers.
Following are the examples:
1. Presentation will create an object of business layer or business facade. But it will expect the logical entity from business layer.
Business layer will create the object of DataAccess and will expect the logical entity from DataAccess to perform business operations.
DataAccess will do whatever it would like to do to get the information from database. So if you need to connect the oracle / sql /sqllite / files system whatever but it will convert or say initialize the Logical entity (entity is a Class only consisting of properties).
So every layer will have their own responsibility and perform the operation it is responsible for.
So I think your db related operations will go in DataAccess.

Data Access Layer

how we can create a generic data access layer that can be used by any asp.net application using different datasource provider or webservices?
Can we create data access layer for application that consumes webservice?
You might look into the Repository Pattern. Repository is a facade that presents persisted objects as though they are in a collection in memory. Whichever provider you choose to get data is hidden behind the Repository interface.
IRepository with LINQ to SQL
Code Project Tutorial
A sample by Fredrik Kalseth
You have plenty of options! :-)
You mention you want to use the data access layer (DAL) from asp.net and web services. No problem.
Basically, what you need to figure out is a basic design you want to follow, and encapsulate the DAL into its own assembly which can be used / referenced from various consumers.
There are numerous ways of doing this:
create a Linq-to-SQL mapping for your tables, if you're using SQL Server as your backend, and use the Linq-to-SQL entities and methods
create a repository pattern (for each "entity", you have an "EntityRepository" class, which can be used to retrieve entities, e.g. EntityReposity.GetByID(int id), or EntityRepository.GetByForeignKey(string fk) or whatever
use some other means of accessing the data (NHibernate, your own ADO.NET based mapper)
you could actually also use webservice calls as your data providers
Your biggest challenge is to define a standard way of doing things, and sticking to it.
See some articles - maybe they'll give you an idea:
Creating a Data Access Layer in .NET - Part 1
Building a DAL using Strongly Typed TableAdapters and DataTables in VS 2005 and ASP.NET 2.0
Try the tutorials at www.asp.net:
DataAccess
Woah, there are a ton of resources out there. Best advice to start is to find a pattern that you feel comfortable with and stick to it for the project, there is nothing worse then changing your mind 3/4 the way in.
One that I have found and like to use is the Repository or Provider patter. The Repository pattern just makes sure you have standard access to repositories, like your store catalog or CMS system. You create an interface that in my case expose sets of IQueryable the object or the data model are just standard c# classes with now extra fluff POCO (Plain Old CLR Objects).
public interface ICMSRepository {
IQueryable<ContentSection> GetContentSections();
void SaveContentSection(ContentSection obj);
}
Then just implement the interface for your different providers, like a LINQ to SQL context, making sure to return the POCO objects as queryable. The nice thing about this is that you can then make extension methods off of the IQueryable to get what you need easily. Like:
public static IQueryable<ContentSection> WithID(this IQueryable<ContentSection> qry, int ID) {
return from c in qry select c;
}
//Allow you to chain repository and filter to delay SQL execution
ICMSRepository _rep = new SqlCMSRepository();
var sec = _rep.GetContentSections().WithID(1).SingleDefault();
The nice thing about using the Interface approach is the ability to test and mock it up or dependency inject your preferred storage at run time.
Another method I have used and is used in the ASP.Net framework a lot is the Provider model. This is similar except instead of an Interface you create a singleton abstract class, your implementations on top of the abstract class will then define the storage access means (XML, Flat file, SQL, MySql, etc). The base abstract class will be also be resonsible for creating it's singleton based on configuration. Take a look at this for more info on the provider model.
Otherwise you can look at this similar question.
IRepository of T is general good approach. This Interface should expose GetAll, GetByID, Insert, Delete and Submit methods.
But it's important to keep your business logic out of Repository class, and put it to custom logic/service class.
Also, if you return IQueriable in your GetAll method, what you can often see in various implementation of IRepository, UI layer can also query against that IQueriable interface. But querying of object graph should remain in Repository layer. There's a lot debate around this issue.
Look at using the Interfaces:
IDbConnection
IDbCommand
IDbDataAdapter
IdataReader

Categories

Resources