I'm currently trying to find the right architecture for my Solution, but I have one doubt, is it wrong to create a Repository Interface containing methods with lambda expression arguments?
For example:
IEnumerable<TEntity> GetAll(Func<TEntity, bool> where);
Using Entity Framework i can easily implement this on my concrete repository:
public virtual IEnumerable<TEntity> GetAll(Func<TEntity, bool> where)
{
return DbSet.Where(where).ToList();
}
But our main objective by separating data access on another layer is to provide an abstraction on the data access and facilitate future data hosting migrations.
Is it possible to implement this repository method on another Data access technology? For example sql queries directly to database?
Yes, this is possible, but it is not very simple. What you need to do is to implement an IQueryable<T> LINQ Provider.
This walkthrough from Microsoft explains how to do it. You may need to change the signature of your method to take IExpression<Func<TEntity, bool>>, and returning IQueryable<TEntity>:
public virtual IQueryable<TEntity> GetAll(IExpression<Func<TEntity, bool>> where)
{
return DbSet.Where(where).ToList();
}
Related
My first question on SO!
What I'm working on is a Webforms page that's has a lot ASP textboxes, datepickers and dropdowns. Right now I'm using ADO.net for all of these controls to do CRUD operations.
I'm already a great deal into this project, but I can't help wondering if I could be doing this in an easier or more efficient way. So far I'm using the SqlDataReader class for everything.
If someone could break down the different options available to me or point me to some good information, I'd appreciate it. I know it's a pretty broad topic. I'm kind of aware of LINQtoSQL and EntityFramework.
So my question really is: How does ADO.net compare to LINQtoSQL or EntityFramework?
you should read up on one sample each of ADO.NET, Linq 2 SQL and Entity Framework and implement them to know the pros/cons of each. a simple web search should give you samples.
Linq2Sql and EF will require very SQL query writing from you. once you have an initial grasp of these 3 things individually, follow this simple pattern in your code:
define an interface for your data access.
let your code behind (ascx.cs and aspx.cs) work with the interface.
define concrete implementations of the interface based on ADO.NET, Linq2Sql or EF.
e.g.
public interface IRepository
{
MyDto GetData(int id);
// and so on
}
public class EntityFrameworkRepository : IRepository
{
public MyDto GetData(int id)
{
using (var db = new MyDbContext())
{
var myDtoEntity = db.MyDtoEntity.FirstOrDefault(m => m.Id == id);
// extension method to transform DB objects into DTOs
return myDtoEntity.ToMyDto();
}
}
}
// similarly you can do:
public class Linq2SqlRepository : IRepository
{
// so on..
}
// now for all your aspx.cs pages: derive them from a base page,
// and in the base page
// have a variable like this, so that all pages have access to this.
public IRepository Repository {get; set;}
// you can have static instances as well for one time initialization.
// you can initialize the Repository with a particular concrete implementation
// or inject it. (if you're well versed with Dependency Injection)
using the above way, all your code will work off the Interface, and you just need to change one place if you decide to change the implementation.
In my project, i have first created my Data Access Layer using Entity Framework with the following projects in a single solution,
1.Domain Model - Entity Model (.edmx)
2.Services - Business Services, Dtos, Infrastructure(Configurator), Interfaces and Models(Repository)
Now the problem is, i want to connect this data access layer to my MVC project, i do not know how to make the data access layer projects to behave as the models for my mvc project. So can anyone tell me how to connect my data access layer into my controllers and views.. any references is appreciated. Thanks in Advance !
I think what you're asking is what's the best way for controllers to interact with your services and data layer?
One option is to use the mediator pattern, and decouple the services from the controllers.
There's a great implementation for ASP.NET MVC apps: ShortBus, also available on nuget that I've used in a number of projects, and so far it's worked great.
One of the nice things about ShortBus is it's support for dependency injection. In the example below, all the services are created with Ninject, and require the appropriate registration.
The basic idea is you define queries and commands that the controllers will use, and then add handlers to perform the actual work.
public class AddUser : ICommand<User>
{
public string Email { get; set; }
}
and then a handler:
public class AddUserHandler : ICommandHandler<AddUser, User>
{
private IDatabaseService _database;
private IEmailService _email;
public AddUserHandler(IDatabaseService database, IEmailService email)
{
_database = database;
_email = email;
}
public User Handle(AddUser command)
{
bool created = _database.CreateUser(command.Email);
if (created)
{
_email.SendWelcome(command.Email);
}
}
}
Then inside your controller, all you'd do is issue the command:
public class UsersController : Controller
{
private IMediator _mediator;
public UsersController(IMediator mediator)
{
_mediator = mediator;
}
public ActionResult Create(string email)
{
User user = _mediator.Send(new AddUser("foo#bar.com"));
}
}
The things I like about this pattern are:
Controllers don't need to know how to create a user. It issues a command, and the appropriate business logic handles it.
Each handler can require the services it needs. There's no need to pollute the controllers with services only used by a single action.
It's really easy to unit test. I use a mock, and only need to verify that _mediator.Send() was called with the correct parameters. Then to test the handler, I mock IDatabaseService and IEmailService and verify they are called correctly in the 2 cases.
Commands and queries can be reused, and again, the caller never needs to know what's required to handle the request.
As for the Views, I'd recommend ViewModels.
Each View gets it's own ViewModel, which holds whatever is required for showing that particular page. You'd then map your domain objects to their own individual ViewModels, possibly with AutoMapper.
What's nice about ViewModels is you can format the data appropriately (formatting a DateTime maybe), and then your Views don't need any special logic. If later you decide to update the DateTime format, you only need to change it in one place.
Create a (shared) interface to pass to the layer that's between the DAL and MVC, especially if you're unit testing. Use a repository pattern. Check it out here:
http://csharppulse.blogspot.com/2013/09/learning-mvc-part-5repository-pattern.html
This should get you going...
I have binary data in my database that I'll have to convert to bitmap at some point. I was thinking whether or not it's appropriate to use a repository and do it there. My consumer, which is a presentation layer, will use this repository. For example:
// This is a class I created for modeling the item as is.
public class RealItem
{
public string Name { get; set; }
public Bitmap Image { get; set; }
}
public abstract class BaseRepository
{
//using Unity (http://unity.codeplex.com) to inject the dependancy of entity context.
[Dependency]
public Context { get; set; }
}
public calss ItemRepository : BaseRepository
{
public List<Items> Select()
{
IEnumerable<Items> items = from item in Context.Items select item;
List<RealItem> lst = new List<RealItem>();
foreach(itm in items)
{
MemoryStream stream = new MemoryStream(itm.Image);
Bitmap image = (Bitmap)Image.FromStream(stream);
RealItem ritem = new RealItem{ Name=item.Name, Image=image };
lst.Add(ritem);
}
return lst;
}
}
Is this a correct way to use the repository pattern? I'm learning this pattern and I've seen a lot of examples online that are using a repository but when I looked at their source code... for example:
public IQueryable<object> Select
{
return from q in base.Context.MyItems select q;
}
as you can see almost no behavior is added to the system by their approach except for hidding the data access query, so I was confused that maybe repository is something else and I got it all wrong. At the end there should be extra benifits of using them right?
Update: as it turned out you don't need repositories if there is nothing more to be done on data before sending them out, but wait! no abstraction on LINQ query? that way client has to provide the query statements for us which can be a little unsafe and hard to validate, so maybe the repository is also providing an abstraction on data queries? if this is true then having a repository is always an essential need in project architecture!! however this abstraction can be provided by using SQL stored procedures. what is the choice if both options are available?
Yes, that's the correct way: the repository contract serves the application needs, dealing ony with application objects.
The (bad)example you are seeing most of the time couples any repository implementation to IQueryable which may or may be not implemented by the underlying orm and after all it is an implementation detail.
The difference between IQueryable and IEnumerable is important when dealing with remote data, but that's what the repository does in the first place: it hides the fact you're dealing with a storage which can be remote. For the app, the repository is just a local collection of objects.
Update
The repository abstracts the persistence access, it makes the application decoupled from a particular persistence implementation and masks itself as a simple collection. This means the app doesn't know about Linq2Sql, Sql or the type of RDBMS used, if any. The app sends/receives objects from the repo, while the repo actually persists or loads objects. The app doesn't care how the repo does it.
I consider the repository a very useful pattern and I'm using it in every project, precisely because it marks the boundry between the application (as the place where problems and solutions are defined and handled) and storage/persistence where data is saved.
You can make you repository a generic one and can get mode value out of it. And make sure you are using an Interface (IItemRepository ) to access repositories in manager layer so that the you can replace your repositories with some another data access method using new repository implementation. Here is an good example how to do this.
I have two data sources, the first one uses OLEDB to connect and other uses SQL Data Provider.
I always create a DAL to encapsulate data access logic, but this time it seams I have to create two different DAL (OLDB and SQLProvider.
Will this is the right approach or I can communicate with single DAL. Please suggest what is the best approach followed while communicating different data source from ASp.NET application.
Thanks
You are right that you need to encapsulate the data access logic in a separate layer if you want to access two different data sources,
The key is to make sure that your other code, uses an interface, not an implementation, to access your DAL.
So for example:
public interface IRepository
{
Person GetPersonById(Guid id);
}
public class OleRepository : IRepository
{
public Person GetPersonById(Guid id)
{
// Do some Ole specific stuff to return a person
}
}
public class SqlRepository : IRepository
{
public Person GetPersonById(Guid id)
{
// Do some Sql Server specific stuff to return a person
}
}
In your code, you would program against the IRepository interface and you wouldn't depend on a specific implementation. At runtime, you would select the right Repository implementation (for example with Dependency Injection).
I have implemented the repository pattern using the following generic interface.
public interface IRepository<T> where T : class
{
IQueryable<T> All { get; }
IQueryable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties);
T Find(int id);
void InsertOrUpdate(T updateObject);
void Delete(int id);
void Save();
}
I then create the individual repositories and call them from my service layer.
I have a table in my database that is populated with the last date that one of our data feeds runs (it will only ever contain one record). All I need to do is get this date from the database. What is a good way to do this? Surely creating a repository for this simple read only table is overkill? Should I create a function or stored proc in the database to return this date and if I do how would it fit in with the repository pattern?
You shouldn't inherit from the general IRepository<T> interface because most of those methods won't make any sense.
But since you already state that you could use a stored procedure, a LINQ query or maybe even esql it would still be a good idea to encapsulate the data retrieval. What if you want to change the mechanism or apply some caching?
Also think about unit testing, your code depends on this 'last date', so in your unit tests you want to be able to supply different dates. A mockable repository will be the easiest.
Maybe you can add the LastModificationDate as a function to your ObjectContext. Then you have on single point of access and in a FakeObjectContext you can return specific dates for testing purposes.
If you can use an abstract for the repository definition rather than an interface, you can add the date-code directly to the abstract and have it inherited by all your repositories.