Entity Framework has changed drastically since they have introduced version 1. EF 4.1 has improved Code First and Fluent mappings which are really impressive. However, I have a worry about complex query implementations on EF 4.1 because it depends on DbContext strongly. Entity SQL and Linq to Entities keep on changing it's behavior with SQL queries. I feel we need a strong Query mechanism like HQL or Criteria to overcome this. What you think ?
Many modern .NET ORMs provide an IQueryProvider implementation (including NHibernate). I choose to remove the direct dependency on EF by using POCO T4 template, then modifying it to generate an interface (IMyRepository) that returns plain IQueryables instead of ObjectSets. The underlying implementation of IMyRepository using a ObjectContext. If we decide to move away from EntityFramework, we can just change the implementation of IMyRepository to use someone else's LINQ IQueryProvider.
Further, this allows us to work in a distributed scenario. For example, one implementation of IMyRepository lives on the client and uses DataServiceClient (WCF Data Services) to call out to the server, which has a different implementation of IMyRepository, which uses Entity Framework directly.
In the case of Code First, this is also fairly easy to do. Your classes are already POCOs...so just make your DbContext implement an interface that returns IQueryables instead of DbSets.
I personally then inject the IMyRepository using dependency injection.
My Generic repository Looks like follows
public class Repository<TEntity, TPrimaryKey>: IRepository<TEntity, TPrimaryKey> where TEntity : class
{
public IQueryable<TEntity> GetQuery()
{
return this.UnitOfWork.GetQuery<TEntity>();
}
public IQueryable<T> LoadType<T>() where T : class
{
return this.UnitOfWork.GetQuery<T>();
}
}
And My Unit of Work goes here
public class UnitOfWork
{
/// <summary>
/// Gets the query.
/// </summary>
/// <typeparam name="TEntity">The type of the entity.</typeparam>
/// <returns></returns>
public IQueryable<TEntity> GetQuery<TEntity>() where TEntity:class
{
return this.DbContext.Set<TEntity>();
}
}
Related
I am implementing a form of CQRS that uses a single data store but separate Query and Command models. For the command side of things I am implementing DDD including Repositories, IoC and Dependency Injection. For the Query side I am using the Finder pattern as described here. Basically, a finder is similar to a Repository, but with Find methods only.
So in my application for the read side, in my DAL, I use ADO.net and raw SQL to do my queries. The ADO.Net stuff is all abstracted away into a nice helper class so that my Finder classes simply pass the query to the ADO helper which returns generic data objects which the finder/mapper class turns into read models.
Currently the Finder methods, like my command repositories, are accessed through interfaces that are injected into my controllers, but I am wondering if the interfaces, DI and IoC are overkill for the query side, as everything I have read about the read side of CQRS recommends a "thin data layer".
Why not just access my Finders directly? I understand the arguments for interfaces and DI. ie Separation of Concerns and testability. In the case of SOC, my DAL has already separated out database specific logic by using a mapper class and putting the ADO.net stuff in a helper class. As far as testing is concerned, according to this question unit testing read models is not a necessity.
So in summary, for read models, can I just do this:
public class PersonController : Controller
{
public ActionResult Details(int id)
{
var person = new Person();
person = PersonFinder.GetByID(id);
// TODO: Map person to viewmodel
return this.View(viewmodel);
}
}
Instead of this:
public class PersonController : Controller
{
private IPersonFinder _person;
public PersonController(IPersonFinder person)
{
_person = person;
}
public ActionResult Details(int id)
{
Person person = _person.GetByID(id);
// TODO: Map person to viewmodel
return this.View(viewmodel);
}
}
Are you using both IoC and DI? That's bad ass! Anyways, the second version is the better one because it doesn't depend on a static class. Using statics will open Pandora's box, don't do it, for all the reasons that using static is bad.
You really don't get any benefits for using a static class and once you are already using a DI Container, there's no additional cost. And you are using the Finders directly but you let the DI Container instantiate one instead of you calling a static object.
Update
A thin read layer refers to using a simplified read model instead of the rich domain objects. It is unrelated to DI, it doesn't matter how the query service is built or by whom, it matters to not involve the business objects in queries.
Read/Write separation is completely unrelated to coding techniques like dependency injection. Your read models are serving fewer purposes than your combined read/write models were before. Could you consider ditching all the server-side code and just using your database's native REST API? Could you wire your controller to directly query the database with SQL and return the data as JSON? Do you need a generic repository-like pattern to deal with specific read requests?
I need to implement MVC architecture in my company, So can anyone suggest where to keep frequently used methods to call on all pages. Like:
states ddl, departments ddl also roles list and etc...
Please give me suggestions where to keep them in architecture.
Thanks
There are different solutions depending on the scale of your application. For small projects, you can simply create a set of classes in MVC application itself. Just create a Utils folder and a DropDownLists class and away you go. For simple stuff like this, I find it's acceptable to have static methods that return the data, lists, or enumerations you require.
Another option is to create an abstract MyControllerBase class that descends from Controller and put your cross-cutting concerns in there, perhaps as virtual methods or properties. Then all your actual controllers can descend from MyControllerBase.
For larger applications, or in situations where you might share these classes with other MVC applications, create a shared library such as MySolution.Utils and reference the library from all projects as required.
Yet another possibility for larger solutions is to use Dependency Injection to inject the requirements in at runtime. You might consider using something like Unity or Ninject for this task.
Example, as per your request (also in GitHub Gist)
// declare these in a shared library
public interface ILookupDataProvider
{
IEnumerable<string> States { get; }
}
public class LookupDataProvider: ILookupDataProvider
{
public IEnumerable<string> States
{
get
{
return new string[] { "A", "B", "C" };
}
}
}
// then inject the requirement in to your controller
// in this example, the [Dependency] attribute comes from Unity (other DI containers are available!)
public class MyController : Controller
{
[Dependency]
public ILookupDataProvider LookupDataProvider { get; set; }
public ActionResult Index()
{
var myModel = new MyModel
{
States = LookupDataProvider.States
};
return View(myModel);
}
}
In the code above, you'll need to configure your Dependency Injection technology but this is definitely outside the scope of the answer (check SO for help here). Once configured correctly, the concrete implementation of ILookupDataProvider will be injected in at runtime to provide the data.
One final solution I would suggest, albeit this would be very much overkill for small projects would be to host shared services in a WCF service layer. This allows parts of your application to be separated out in to highly-scalable services, should the need arise in the future.
This is more of a design concern.
Im building an app and i have created my Repository Pattern Structure as following :
My Core name space is the DAL/Repository/BusinessLogic layers assembly.
By the way, i am using Dapper.NET micro ORM as my data connection, thats why you will see an extension on my SqlConnection object.
For my data access, i have created a base repository class :
namespace Core
{
public class BaseRepository<T>: IDisposable where T : BaseEntity
{
protected SqlConnection conn = null;
#region Constructors
public BaseRepository() : this("LOCAL")
{
}
public BaseRepository(string configurationKey = "LOCAL")
{
conn = new SqlConnection(ConfigurationManager.ConnectionStrings[configurationKey].ConnectionString);
}
#endregion
#region IDisposable
public void Dispose()
{
conn.Dispose();
}
#endregion
/// <summary>
/// returns a list of entities
/// </summary>
/// <typeparam name="T">BaseEntity type</typeparam>
/// <param name="sproc">optional parameters, stored procedure name.</param>
/// <returns>BaseEntity</returns>
protected virtual IEnumerable<T> GetListEntity(string sproc = null)
{
string storedProcName = string.Empty;
if (sproc == null)
{
storedProcName = "[dbo].sp_GetList_" + typeof(T).ToString().Replace("Core.",string.Empty);
}
else
{
storedProcName = sproc;
}
IEnumerable<T> items = new List<T>();
try
{
conn.Open();
items = conn.Query<T>(storedProcName,
commandType: CommandType.StoredProcedure);
conn.Close();
}
finally
{
conn.Close();
}
return items;
}
}
}
And for each entity that I have, lets say ExtendedUser, Messages , i am creating its on Interface-Class pair like this :
namespace Core
{
public class ExtendedUserRepository : BaseRepository<UsersExtended>,IExtendedUserRepository
{
public ExtendedUserRepository() : this("PROD")
{
}
public ExtendedUserRepository(string configurationKey) : base(configurationKey)
{
}
public UsersExtended GetExtendedUser(string username)
{
var list = GetListEntity().SingleOrDefault(u => u.Username == username);
return list;
}
public UsersExtended GetExtendedUser(Guid userid)
{
throw new NotImplementedException();
}
public List<UsersExtended> GetListExtendedUser()
{
throw new NotImplementedException();
}
}
}
etc.
The above code is just one of the entities :ExtendedUser.
The question is : should i create a Interface-ClassThatImplemenetsInterface pair for each entity that i have ? or should i have only one RepositoryClass and one IRepository interface with all my methods from all of my entities?
I don't think you need to create interface without the reason. I even don't see why you need base repository class here. I even think this is not repository but DAL (Data Access Layer) but this is defintion argue.
I think good DAL implementation should decouple database structure from business logic structure - but hardcoding sp_GetList_XXXEntityNameXXX pattern or passing stored procedure name outside of DAL is not decoupling.
You are very optimistic or your application is really simple if you think all entity lists are obtained in one way and you will always need full set of entities in business logic without any parameters.
Separating interface from implementation is only needed if you plan to replace/wrap out different implementations, or mix few interfaces in one class. Otherwise it is not required.
Don't think in terms of entities when creating repositories. Repository contains business logic and should be built over scenarios of usage. Having classes like you have is more about Data Access Layer - and DAL is built over queries you would need in business logic. Probably you would never need list of ALL users at once - but would very often need list of active users, privileged users etc.
It is really hard to predict what queries you will need - so I prefer to start designing from business logic and add DAL methods by the way.
A system with a complex domain model often benefits from a layer, such
as the one provided by Data Mapper (165), that isolates domain objects
from details of the database access code. In such systems it can be
worthwhile to build another layer of abstraction over the mapping
layer where query construction code is concentrated.
http://martinfowler.com/eaaCatalog/repository.html
With a generic repository you can have common methods like findBy(array('id' => 1)), findOneBy(array('email' => 'john#bar.com')), findById(), findAll() and so on. Indeed, it'll have one interface.
You'll always have to create a concrete implementation that will indicates which is the domain object that will be managed by the repository in order to accomplish this getUsersRepository().findAll()
Moreover, if you need more complicated queries, you can create new methods on the concrete implementation, such as findMostActiveUsers() and then reuse it across your application.
Now, answering your question:
Your application will be expecting for at least one interface (that generic one, with the common methods). But if you manage to have specific methods, like the one I've just mentioned above, you'd be better having another interface (e.g. RepositoryInterface and UsersRepositoryInteface).
With that in mind, then you'll only depend on the repository interface. The query construction will be encapsulated by the concrete implementation. So you'll be able to change your repository implementation (e.g. using an full-blow ORM) without affecting the rest of your application.
I'm running into issues with multiple contexts and the main solution that comes up is to share the context between repositories however I haven't found a good example on how to do this.
For reference, I'm using an MVC Web App to connect to my data layer. I'd like to have one context per user request (assuming this is correct).
Thanks,
Edit -
This is my solution with the help of BrokenGlass's links and the following SO Question:
I essentially implemented the Unit Of Work pattern and Dependency Injection. I should have mentioned in addition to using MVC, I'm also using Ninject.
In a given repository constructor (see the link below for Unit Of Work pattern details):
public class PersonRepository : IPersonRepository
{
private readonly MyContext _context;
public PersonRepository(IUnitOfWork unitOfWork)
{
if (unitOfWork == null)
throw new ArgumentNullException("unitOfWork");
_context = unitOfWork as MyContext;
}
//...
}
In my MVC App in the NinjectMVC3 class (the key being the InRequestScope() method):
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUnitOfWork>().To<MyContext>().InRequestScope();
kernel.Bind<IPersonRepository>().To<PersonRepository>();
//...
}
Your repository layer should provide a unit of work that represents a single request and uses a context object that is then used on all individual repositories that are needed to fulfill the request.
For HTTP / web apps specifically you can cache the db context in the HttpContext.Current.Items which stores shared data for each HTTP request. Also check out this similar SO thread for details: attaching linq to sql datacontext to httpcontext in business layer
My answer to C#/EF and the Repository Pattern: Where to put the ObjectContext in a solution with multiple repositories? provides an implementation of a RepositoryProvider that works with a single instance of an ObjectContext. You could use the code the same way, with a LINQ-to-SQL DataContext instead of an EF ObjectContext. The benefit of the RepositoryProvider over Ninject, is that the RepositoryProvider implementation is not bound to a specific DI framework, and can itself be configured in any DI framework.
In addition, you can manage creation and scoping of the DataContext to either a Thread or a WebRequest (such as in #BrokenGlass's answer with HttpContext.Current.Items) by using the DataContextFactory class from here.
I have a property on my BaseController called DataContext that holds my LINQ to SQL data context (or fake context for testing). When using a parameterless constructor (in other words, when a request to ASP.NET MVC is made), a new instance of my LINQ to SQL data context is assigned to the property:
public class BaseController : Controller {
public IDataContextWrapper DataContext { get; set; }
public BaseController() : this(new DataContextWrapper<MyDataContext>()) { }
public BaseController(IDataContextWrapper context) {
DataContext = context;
}
}
Also in my BaseController, I set some global ViewData items:
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
ViewData["Example"] = DataContext.Table<Example>().Count();
base.OnActionExecuting(filterContext);
}
This is working fine for almost every action. The only one that doesn't work is the Logout action on my AccountController:
public ActionResult Logout() {
FormsAuth.SignOut();
return RedirectToResult("Login");
}
This raises a NullReferenceException during BaseController.OnActionExecuting. When executing that particular action, the DataContext property is null.
Why would this only occur on one action?
Note: IDataContextWrapper and DataContextWrapper simply wraps the existing functionality of the LINQ to SQL DataContext object so that it can be replaced with a fake context in unit tests. It doesn't do any disposing on its own, but leaves it up to the underlying DataContext, so I'm pretty certain that's not the problem.
To follow up my comment, check out this link and more specifically the link Microsoft documentation here which state:
In general, a DataContext instance is designed to last for one "unit of work" however your application defines that term. A DataContext is lightweight and is not expensive to create. A typical LINQ to SQL application creates DataContext instances at method scope or as a member of short-lived classes that represent a logical set of related database operations.
Microsoft did a terrible job explaining this and frankly explaining using Linq in an n-tier environment in the first place. In my particular case, I had one (static) datacontext implemented via Singleton pattern, which I am guessing is what you have done as well. ( As it is the most logical design, IMHO ). This however, is extremely NOT the way to do things. In my case, the fix was actually pretty easy, changing my GetDataContext() call to return a new DataContext every time, instead of returning the static instance. This however, you will find, creates a whole new crop of problems. None of them are insurmountable once you figure them out, but definitely a pain.
If you have such a setup ( Singleton accessors for your DataContext), change it to see if it fixes your problem.
Regardless, do not use a global DataContext, nor persist a DataContext if dealing with an n-tier architecture.
Even if this doesn't solve your particular problem, I highly suggest you re-architect your solution to make DataContexts have a unit of work lifespan, if it hasn't bitten you already, it will.
For reasons that I don't quite understand, when a new AccountController is created for the Logout action, ASP.NET MVC is using the second constructor with a null parameter (could be a bug?). I changed the class to create a new default DataContext when the parameter is null:
public class BaseController : Controller {
public IDataContextWrapper DataContext { get; set; }
public BaseController() : this(null) { }
public BaseController(IDataContextWrapper context) {
DataContext = dataContext ?? new DataContextWrapper<MyDataContext>();
}
}
Now it works.
It strikes me as strange that ASP.NET MVC used the default constructor in some cases, and an overload in others, though. Can anyone shed some light on this?