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.
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 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.
I'm beginning to work on the caching infrastructure for my ASP.NET MVC site. The problem is, I can't seem to find a reasonable place for data caching (other than 'everywhere')
Right now my architecture looks like this:
Controller -> Service Layer -> Repository. The repository uses Linq to SQL for data access.
The repository exposes generic methods like Insert, GetById, and GetQueryable, which returns an IQueryable that the service layer can further refine.
I like the idea of putting caching in the repository layer, since the service layer shouldn't really care where the data comes from. The problem though is with cache invalidation. The service layer has more information about when data becomes stale than the repository. For instance:
Suppose we have a Users table and an Orders table (the canonical example). The service layer offers methods like GetOrder(int id), which would call the repository layer:
public Order GetOrder(int id)
{
using(var repo = _repoFactory.Create<Order>())
{
return repo.GetById(id)
}
}
or
repo.GetQueryable(order => order.Id == id && order.HasShipped == false).Single();
If we cache in the repository layer, it seems like it would be very limited in knowing when that order data has changed. Suppose the user was deleted, causing all their orders to be deleted with a CASCADE. The service layer could invalidate the Orders cache, since it knew the user was just removed. The repository though (since it's a Unit of Work), wouldn't be aware. (Ignore the fact that we shouldn't be querying orders for a deleted user, since it's just an example).
There's other situations where I think this shows itself. Suppose we want to fetch all the users orders:
repo.GetQueryable(order => order.UserId == userId).ToList()
The repository can cache the results of this query, but, if another order is added, this query is no longer valid. Only the service layer is aware of this though.
It's also possible my understanding of the repository layer is wrong. I sort of view it as a facade around the data source (i.e. changing from L2SQL to EF to whatever, the service layer is unaware of the underlying source).
Realistically, you will need another layer; the data caching layer. It will be used by your service layer when requesting data. Upon such a request, it will decide if it has the data in cache or if it needs to query the appropriate repository. Likewise, your service layer can tell this new data caching layer of an invalidation (the deletion of a particular user, etc.).
What this can mean for your architecture though, is that your data caching layer will implement the same interface(s) your repositories do. A fairly simple implementation would cache the data by entity type and key. However, if you are using a more sophisticated ORM behind the scenes (NHibernate, EF 4, etc.), it should have caching as an option for you.
You could put an event on the objects returned by your repositories, and have the repository subscribe the cache invalidation to a handler.
For example,
public class SomethingRepository{
public Something GetById(int id){
var something = _table.Single(x=>x.id==id);
something.DataChanged += this.InvalidateCache;
return something;
}
public void InvalidateCache(object sender, EventArgs e){
// invalidate your cache
}
}
And your Something object needs to have a DataChanged event and some public method for your service layer to call to trigger it. Like,
public class Something{
private int _id;
public int Id{
get { return _id; }
set {
if( _id != value )
{
_id = value;
OnDataChanged();
}
}
}
public event EventHandler DataChanged;
public void OnDataChanged(){
if(DataChanged!=null)
DataChanged(this, EventArgs.Empty);
}
}
So, all your service layer needs to know is that the data is being changed, and the repository handles the cache invalidation.
I also suggest you take ventaur's advice and put the cache invalidation logic in a separate service. You don't need to go so far as to create a separate "data caching layer", but the logic would be cleaner if kept in a different class.
what's the best practice for creating test persistence layers when doing an ASP.NET site (eg. ASP.NET MVC site)?
Many examples I've seen use Moq (or another mocking framework) in the unit test project, but I want to, like .. moq out my persistence layer so that my website shows data and stuff, but it's not coming from a database. I want to do that last. All the mocking stuff I've seen only exists in unit tests.
What practices do people do when they want to (stub?) fake out a persistence layer for quick and fast development? I use Dependency Injection to handle it and have some hard coded results for my persistence layer (which is really manual and boring).
What are other people doing? Examples and links would be awesome :)
UPDATE
Just a little update: so far I'm getting a fair bit of mileage out of having a fake repository and a SQL repository - where each class implements an interface. Then, using DI (I'm using StructureMap), I can switch between my fake repository or the SQL repository. So far, it's working well :)
(also scary to think that I asked this question nearly 11 months ago, from when I'm editing this, right now!)
Assuming you're using the Repository pattern from Rob Conery's MVC Store Front:
http://blog.wekeroad.com/mvc-storefront/mvc-storefront-part-1/
I followed Rob Conery's tutorial but ran into the same want as you. Best thing to do is move the Mock Repositories you've created into a seperate project called Mocks then you can swap them out pretty easily with the real ones when you instantiate your service. If your feeling adventurous you could create a factory that takes a value from the config file to instantiate either a mock or a real repository,
e.g.
public static ICatalogRepository GetCatalogRepository(bool useMock)
{
if(useMock)
return new FakeCatalogRepository();
else
return new SqlCatalogRepository();
}
or use a dependency injection framework :)
container.Resolve<ICatalogRepository>();
Good luck!
EDIT: In response to your comments, sounds like you want to use a list and LINQ to emulate a db's operations e.g. GetProducts, StoreProduct. I've done this before. Here's an example:
public class Product
{
public int Identity { get; set; }
public string Name { get; set; }
public string Description { get; set; }
//etc
}
public class FakeCatalogRepository()
{
private List<Product> _fakes;
public FakeCatalogCatalogRepository()
{
_fakes = new List<Product>();
//Set up some initial fake data
for(int i=0; i < 5; i++)
{
Product p = new Product
{
Identity = i,
Name = "product"+i,
Description = "description of product"+i
};
_fakes.Add(p);
}
}
public void StoreProduct(Product p)
{
//Emulate insert/update functionality
_fakes.Add(p);
}
public Product GetProductByIdentity(int id)
{
//emulate "SELECT * FROM products WHERE id = 1234
var aProduct = (from p in _fakes.AsQueryable()
where p.Identity = id
select p).SingleOrDefault();
return aProduct;
}
}
Does that make a bit more sense?
Boring or not, I think you're on the right track. I assume you're creating a fakeRepository that is a concrete implementation of your IRepository which in turn is injected into your service layer. This is nice because at some point in the future when you're happy with the shape of your entities and the behavior of your services, controllers, and views, you can then test drive your real Repositories that will use the database to persist those entities. Of course the nature of those tests will be integration tests, but just as important if not more so.
One thing that may be less boring for you when the time comes to create your real repositories is if you use nHibernate for your persistence you will be able let nhibernate generate your database after you create the nhibernate maps for your entities, assuming you don't have to use a legacy schema.
For instance, I have the following method that is called by my SetUpFixture to generate my db schema:
public class SchemaBuilder
{
public static void ExportSchema()
{
Configuration configuration = new Configuration();
configuration.Configure();
new SchemaExport(configuration).Create(true, true);
}
}
and my SetUpFixture is as follows:
[SetUpFixture]
public class SetUpFixture
{
[SetUp]
public void SetUp()
{
SchemaBuilder.ExportSchema();
DataLoader.LoadData();
}
}
where DataLoader is responsible for creating all of my seed data and test data using the real respoitory.
This probably doesn't answer your questions but I hope it serves to reassure you in your approach.
Greg
Although I'm not using Asp.Net or the MVC framework I do have the need to test services without hitting the database. Your question triggered the writing up of a short (ok, maybe not so short) summary of how I do it. Not claiming it's the best or anything, but it works for us. We access data through a repository and when required we plug in an in-memory repository as explained in the post.
http://blogs.microsoft.co.il/blogs/kim/archive/2008/11/14/testable-data-access-with-the-repository-pattern.aspx
I am using a complete in memory database with SQLite and ActiveRecord. Basically we delete and re-create the database before every integration test is being run, so that the data is always in a known state. The contents of the database are inserted through code. So an example would be like this:
ActiveRecord.Initalize(lots of parameters)
ActiveRecord.DropSchema();
ActiveRecord.CreateSchema();
and then we just add lots of customers or whatever, DDD style:
customerRepository.Save(customer);
Another way to solve this could be using NDbUnit to maintain the state of the database.
I know this question is a bit old, but I've finally come up with an answer :)
Firstly, use RavenDb (Embedded). It's part of the RavenDb Document Database. Its a fully in memory database and works perfectly with unit tests :) I've done it with MSTest, NUnit and xUnit.
Secondly, you can use NHibernate with SqlLite if you don't want to use RavenDb. Ayende has a post about using this.
I've gone the route of creating tables and data during a setup method in a unit test class, running tests, then doing clean up during the teardown. Yes, this method works, but if you really end up using your unit tests for debugging purposes, invariably you will run the setup, debug something then stop in the middle without doing the teardown. It's very brittle and you will probably end up (in the long run) with bad data in your test database and/or unusable unit tests. I personally think its best to mock the database layer using a mocking framework. I do understand that sometimes it's best to do logic in the database. For these cases you can use a tool like DBFit to write tests for your database layer.