I've hit on the idea of creating static methods on the partial Linq queries such as
public partial class User
{
public static User FindByGuid(string guid, ApplicationDataContext context)
{
return context.Users.Where(x => x.GUID == guid).Single();
}
}
So, for example, I can easily find a user by doing:
using (var context = new ApplicationDataContext())
{
var user = DataAccess.User.FindByGuid(UsersDropDown.SelectedValue, context);
}
Is this a recognised design pattern? What are the advantages/disadvantages of doing this vs the repository model?
While I don't see a recognized pattern in what your doing here I do see that you are using Dependency Injection by passing the applicationdatacontext into the method as a dependency. The problem here is that you are still tightly coupled to your datacontext regardless of where the dependency is initiated which makes it more difficult to unit test.
Related
Is it possible to have more than one dependency resolver in ASP.NET MVC 3 (similar to the case of ModelBinders and Providers)?
There is one scenario that I could think of where having multiple 'containers' or 'resolvers' is useful and that is multi-tenancy. With multi tenancy you run multiple customers (organizations, with their own set of users) in the same web application, and dynamically switch based on the login, request info, or domain info.
Still, DependencyResolver.Current is -as Darin noted- static, so there's nothing you can (or should do about this). However, you could hide multiple containers behind a single IDependencyResolver abstraction and return an implementation based on some criteria. It might look like this:
public class MultiTenantDependencyResolver
: IDependencyResolver
{
Func<int> tenantIdSelector,;
IDictionary<int, IDependencyResolver> tenantResolvers;
public MultiTenantDependencyResolver(
Func<int> tenantIdSelector,
IDictionary<int, IDependencyResolver> tenantResolvers)
{
this.tenantIdSelector = tenantIdSelector;
this.tenantResolvers= tenantResolvers;
}
private IDependencyResolver CurrentResolver
{
get { return this.tenantResolvers[tenantIdSelector()]; }
}
public object GetService(Type serviceType)
{
return this.CurrentResolver.GetService(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this.CurrentResolver.GetAllInstances(serviceType);
}
}
The following code snippet shows the usage of this MultiTenantDependencyResolver:
var tenantResolvers = new Dictionary<int, IDependencyResolver>
{
{ Tenants.AbcId, BuildResolver(RegisterForTenantAbc) },
{ Tenants.KlmId, BuildResolver(RegisterForTenantKlm) },
{ Tenants.XyzId, BuildResolver(RegisterForTenantXyz) },
};
var multiTenantResolver = new MultiTenantResolver(
() => GetTenantIdFromUrl(), tenantResolvers);
DependencyResolver.SetResolver(multiTenantResolver);
private static int GetTenantIdFromUrl()
{
// TODO: return tenant id
}
private static IDependencyResolver BuildResolver(
Action<IKernel> tenantSpecificRegistrations)
{
var kernel = new Kernel();
// TODO: Tenant agnostic registrations. For instance
kernel.Bind<ITimeProvider>().To<SystemTimeProvider>();
tenantSpecificRegistrations(kernel);
return new NinjectDependencyResolver(kernel);
}
private static void RegisterForTenantAbc(IKernel kernel)
{
// TODO: regisrations for ABC tenant. For instance
kernel.Bind<ILogger>().To<AbcTenantLogger>();
}
Is it possible to have more than one dependency resolver in ASP.NET
MVC 3 (similar to the case of ModelBinders and Providers)?
No, this isn't possible. The DependencyResolver.Current is a static property that could be assigned only one resolver. This being said having more than one dependency resolver in an application hardly makes any sense. The idea is that all your dependencies are managed by a dependency injection framework such as Unity, Ninject or StructureMap. You would then have a custom dependency resolver wrapping your DI framework of choice that will be used by ASP.NET MVC to inject dependencies in various objects of the execution pipeline.
You are comparing it with model binders in your question but this comparison is unfair because a model binder is related to a specific type that it is designed to bind. Basically you could have many custom model binders for multiple view models.
You also seem to have mentioned some providers in your question but unfortunately you haven't beeen very specific so it's a bit harder to comment on this one.
Entity Framework 4, Ninject 3, MVC3
Currently in my web app i have been using a rather rudimentary approach to per request instantiation of an Object Context. So I am experimenting with Ninject, and some old sample code, but I am unsure how to proceed with the following..
Effectively I want to be able in the controller to do the equivalent of: DB_Entities.Current.Albums ... Should i be instantiating a StandardKernel every time?
The sample i was looking at was using the following: MvcApplication.Container.Get(); but in Ninject 3 with the App_Start hookup I dont have access to Container..
My attempt to replicate the above line, is failing at runtime.
using MusicStoreEntities;
using Ninject;
using TestMVC3WithIOC.App_Start;
using System.Data.Objects;
namespace TestMVC3WithIOC.Models
{
public partial class MusicStoreEntities
{
public static MusicStoreEntities Current
{
get
{
using (IKernel kernel = new StandardKernel())
{
return (MusicStoreEntities)kernel.Get<ObjectContext>();
}
}
}
}
}
Also, note, that in App_Start\NinjectWebCommon.cs I have the following modification:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ILogger>().To<NLogger>();
kernel.Bind<ObjectContext>().To<MusicStoreEntities>().InRequestScope();
}
Although a workable solution, it seems ill-advised to pass the entire Kernel into a class, because it tends to obscure the classes actual, specific dependencies. A better approach is to pass a factory dependency into your controller's constructor.
public partial class MusicStoreEntities
{
private readonly IEntitiesFactory _factory;
public MusicStoreEntities(IEntitiesFactory factory)
{
_factory = factory;
}
}
IEntitiesFactory has a simple implementation with a single method GetObjectContext().
(I believe also the "Unit of Work" pattern is popular at the moment, but I can't really speak to that as I haven't used it. Maybe worth looking into.)
I'm using an EF Code First approach with an ASP.NET MVC 3 application, and instead of re-creating the wheel, I was wondering if there already exists a solid base Repository class that my custom Repository classes could extend in order to provide default functionality out of the box (e.g. basic CRUD, etc...).
So something like this ...
public class CustomerRepository : BaseRepository { ... }
... would therefore provide a default way to work with Customer objects out of the box. I'd like to then inject an ICustomerRepository into my MVC controllers and have the functionality available to me there.
I'm sure something like this already exists out there as I've done something similar with NHibernate.
Thanks
No, there is no built-in repository, other than EF itself (which is in and of itself an implementation of the Unit of Work pattern, and DbSet's are basically Repositories).
There is currently a debate in the software community over whether generic repositories have much real value. For testing purposes, many argue, they provide easy unit testing. Others say that unit testing repositories doesn't help because mocked repositories don't behave the same way that real ones do (because of the linq -> Sql translation layer, which doesn't exist in a mocked repository).
Many are suggesting that you do integration testing against EF using an in-memory database like SqlLite rather than unit testing it.
Still, if you are intent on using repositories, there are many examples out there on the net, with varying styles and methods. Or you can roll your own. MS does not provide one.
In my experience, write your own repositories is redundant because EF implements this pattern already through DbSet's.
I worked with MVC3 + EF Code Fisrt in a recent project. We started implementing a generic repository following some tutorials and soon we realized that we are writing a lot of unnecessary and redundant code. Actually, the repositories were given us nothing but hiding a lot of the DbSet's functionality. Finally, we decided to remove them and work with our DbContext and DbSet's directly.
But, how about complex business logic beyond simple CRUD operations?
Well, we exposed all complex functionality like queries and multiple CRUD operations through a service layer. You can build different service classes by functionality. By example, you can write an AccountService to manage all functionality related with user accounts. Something like this:
public class AccountService {
private MyContext ctx;
public AccountService(DbContext dbContext) {
this.ctx = (MyContext)dbContext;
}
/// <summary>
/// Gets the underlying DbContext object.
/// </summary>
public DbContext DbContext {
get { return ctx; }
}
/// <summary>
/// Gets the users repository.
/// </summary>
public DbSet<User> Users {
get {return ctx.Users;}
}
public bool ValidateLogin(string username, string password) {
return ctx.Users.Any(u => u.Username == username && u.Password == password);
}
public string[] GetRolesForUser(string username) {
var qry = from u in ctx.Users
from r in u.Roles
where u.Username == username
select r.Code;
return qry.ToArray<String>();
}
public User CreateUser(string username, string password) {
if (String.IsNullOrWhiteSpace(username)) throw new ArgumentException("Invalid user name");
if (String.IsNullOrWhiteSpace(password)) throw new ArgumentException("Invalid password");
User u = new User {
Username = username.Trim().ToLower(),
Password = password.Trim().ToLower(),
Roles = new List<Role>()
};
ctx.Users.Add(u);
ctx.SaveChanges();
return u;
}
How about dependency injection?
Using this approach, the only thing we need to inject is the DbContext. The service classes has a constructor that takes a DbContext. So, when your controller constructor takes a service instance the DbContext will be injected to it.
Edit: Example code
This is an example code about how you controller could look:
public class HomeController : Controller {
private readonly AccountService accountService;
public AccountController(AccountService accountService) {
this.accountService = accountService;
}
}
And this could be the DI configuration using NInject:
private static void RegisterServices(IKernel kernel) {
kernel.Bind<MyContext>().ToSelf().InRequestScope();
kernel.Bind<DbContext>().ToMethod(ctx => ctx.Kernel.Get<MyContext>());
}
How about unit testing?
You could build specific interfaces for each service layer class and mock it where you need.
A friend of mine, Sacha Barber wrote a nice article covering some of these ideas.
Link can be found here.
RESTful WCF / EF POCO / Unit of Work / Repository / MEF: 1 of 2
EF has a base class called DbContext. You can add properties of type DbSet<TEntity>
This allows you to do something like this:
public class User {
public int Id { get; set; }
public string Name { get; set; }
}
public class DatabaseContext : DbContext {
public DbSet<User> Users { get; set; }
}
You can now use this like so:
using(var db = new DatabaseContext()) {
User jon = new User {Name = "Jon Smith"};
db.Users.Add(jon);
db.SaveChanges();
var jonById = db.Users.Single(x => x.Id == 1);
}
If you want more abstraction see this post about building a generic repository around EF Entity Framework 4 CTP 4 / CTP 5 Generic Repository Pattern and Unit Testable Just to note, this level of abstraction is not always needed. You should decide if your abblication will truly benefit from adding a generic repository over just using DbContext directly.
I have an MVC app that uses NHibernate for ORM. Each controller takes an ISession construction parameter that is then used to perform CRUD operations on domain model objects. For example,
public class HomeController : Controller
{
public HomeController(ISession session)
{
_session = session;
}
public ViewResult Index(DateTime minDate, DateTime maxDate)
{
var surveys = _session.CreateCriteria<Survey>()
.Add( Expression.Like("Name", "Sm%") )
.Add( Expression.Between("EntryDate", minDate, maxDate) )
.AddOrder( Order.Desc("EntryDate") )
.SetMaxResults(10)
.List<Survey>();
// other logic that I want to unit test that does operations on the surveys variable
return View(someObject);
}
private ISession _session;
}
I would like to unit test this controller in isolation, without actually hitting the database, by mocking the ISession object using Moq or RhinoMocks. However, it is going to be very difficult to mock the ISession interface in the unit test, because it is being used via a fluent interface that chains a number of calls together.
One alternative is to wrap the ISession usage via a repository pattern. I could write a wrapper class something like this:
public interface IRepository
{
List<Survey> SearchSurveyByDate(DateTime minDate, DateTime maxDate);
}
public class SurveyRepository : IRepository
{
public SurveyRepository(ISession session)
{
_session = session;
}
public List<Survey> SearchSurveyByDate(DateTime minDate, DateTime maxDate)
{
return _session.CreateCriteria<Survey>()
.Add( Expression.Like("Name", "Sm%") )
.Add( Expression.Between("EntryDate", minDate, maxDate) )
.AddOrder( Order.Desc("EntryDate") )
.SetMaxResults(10)
.List<Survey>();
}
private ISession _session;
}
I could then re-write my controller to take an IRepository constructor argument, instead of an ISession argument:
public class HomeController : Controller
{
public HomeController(IRepository repository)
{
_repository = repository;
}
public ViewResult Index(DateTime minDate, DateTime maxDate)
{
var surveys = _repository.SearchSurveyByDate(minDate, maxDate);
// other logic that I want to unit test that does operations on the surveys variable
return View(someObject);
}
private IRepository _repository;
}
This second approach would be much easier to unit test, because the IRepository interface would be much easier to mock than the ISession interface, since it is just a single method call. However, I really don't want to go down this route, because:
1) It seems like a really bad idea to create a whole new layer of abstraction and a lot more complexity just to make a unit test easier, and
2) There is a lot of commentary out there that rails against the idea of using a repository pattern with nHibernate, since the ISession interface is already a repository-like interface. (See especially Ayende's posts here and here) and I tend to agree with this commentary.
So my questions is, is there any way I can unit-test my initial implementation by mocking the ISession object? If not, is my only recourse to wrap the ISession query using the repository pattern, or is there some other way I can solve this?
Oren tends to wander around a lot. He used to be a huge proponent of Repositories and Unit of Work. He will probably swing back around again to it, but with a different set of requirements.
Repository has some very specific advantages that none of Oren's comments have quite found solutions for. Also, what he recommends has it's own set of limitaitons and problems. Sometimes I feel like he's just exchanging one set of problems for another. It's also good when you need to provide different views of the same data, such as a Web Service, or Desktop application while still keeping the web app.
Having said that, he has a lot of good points. I'm just not sure there are good solutions for them yet.
Repository is still very useful for highly test driven scenarios. It's still useful if you don't know if you will stick with a given ORM or persistence layer and might want to swap it out with another one.
Oren's solution tends to couple nHimbernate more tightly into the app. That may not be a problem in many situations, in others it might be.
His approach of creating dedicated query classes is interesting, and is sort of a first step to CQRS, which might be a better total solution. But Software development is still so much more art or craft than science. We're still learning.
Rather than mocking out ISession have you considered having your tests inherit from a base fixture that makes use of SQLite?
public class FixtureBase
{
protected ISession Session { get; private set; }
private static ISessionFactory _sessionFactory { get; set; }
private static Configuration _configuration { get; set; }
[SetUp]
public void SetUp()
{
Session = SessionFactory.OpenSession();
BuildSchema(Session);
}
private static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
var cfg = Fluently.Configure()
.Database(FluentNHibernate.Cfg.Db.SQLiteConfiguration.Standard.ShowSql().InMemory())
.Mappings(configuration => configuration.FluentMappings.AddFromAssemblyOf<Residential>())
.ExposeConfiguration(c => _configuration = c);
_sessionFactory = cfg.BuildSessionFactory();
}
return _sessionFactory;
}
}
private static void BuildSchema(ISession session)
{
var export = new SchemaExport(_configuration);
export.Execute(true, true, false, session.Connection, null);
}
[TearDown]
public void TearDownContext()
{
Session.Close();
Session.Dispose();
}
}
Introducing repositories with named query methods does not add complexity to your system. Actually it reduces complexity and makes your code easier to understand and maintain. Compare original version:
public ViewResult Index(DateTime minDate, DateTime maxDate)
{
var surveys = _session.CreateCriteria<Survey>()
.Add(Expression.Like("Name", "Sm%"))
.Add(Expression.Between("EntryDate", minDate, maxDate))
.AddOrder(Order.Desc("EntryDate"))
.SetMaxResults(10)
.List<Survey>();
// other logic which operates on the surveys variable
return View(someObject);
}
Frankly speaking all my memory slots where already occupied BEFORE I got to the actual logic of your method. It takes time for reader to understand which criteria you are building, what parameters are you passing and which values are returned. And I need to switch contexts between lines of code. I start thinking in terms of data access and Hibernate, then suddenly I'm back to the business logic level. And what if you have several places where you need to search surveys by date? Duplicate all this staff?
And now I'm reading version with repository:
public ViewResult Index(DateTime minDate, DateTime maxDate)
{
var surveys = _repository.SearchSurveyByDate(minDate, maxDate);
// other logic which operates on the surveys variable
return View(someObject);
}
It takes me zero efforts to understand what happening here. This method has single responsibility and single level of abstraction. All data access related logic gone. Query logic is not duplicated in different places. Actually I don't care how it is implemented. Should I care at all, if main goal of this method is some other logic?
And, of course, you can write unit test for your business logic with no efforts (also if you are using TDD repository gives you ability to test your controller before you actually write data access logic, and when you will start writing repository implementation, you will have already designed repository interface):
[Test]
public void ShouldDoOtherLogic()
{
// Arrange
Mock<ISurveryRepository> repository = new Mock<ISurveryRepository>();
repository.Setup(r => r.SearchSurveyByDate(minDate, maxDate))
.Returns(surveys);
// Act
HomeController controller = new HomeController(repository.Object);
ViewResult result = controller.Index(minDate, maxDate);
// Assert
}
BTW In-memory database usage is good for acceptance testing, but for unit-testing I think its an overkill.
Also take a look at NHibernate Lambda Extensions or QueryOver in NHibernate 3.0 which use expressions to build criteria instead of strings. Your data access code will not break if you rename some field.
And also take a look on Range for passing pairs of min/max values.
Using a DI container (in this case, Ninject) is it possible - - or rather, wise to cache a frequently used object for the entire application lifetime (or at least until it is refreshed)?
To cite example, say I have a Template. There are many Template objects, but each user will inherit at least the lowest level one. This is immutable and will never change without updating everything that connects to it (so it will only change on administration demand, never based on user input). It seems foolish to keep querying the database over and over for information I know is not changed.
Would caching this be best done in my IoC container, or should I outsource it to something else?
I already store ISessionFactory (nHibernate) as a Singleton. But that's a little bit different because it doesn't include a query to the database, just the back-end to open and close ISession objects to it.
So basically I would do something like this..
static class Immutable
{
[Inject]
public IRepository<Template> TemplateRepository { get; set; }
public static ITemplate Template { get; set; }
public void Initialize()
{
if(Immutable.Template == null)
{
Immutable.Template = TemplateRepository.Retrieve(1); // obviously better logic here.
}
}
class TemplateModule : Module
{
public void Load()
{
Bind<ITemplate>().ToMethod(() => Immutable.Initialize())InSingletonScope();
}
}
Is this a poor approach? And if so, can anyone recommend a more intelligent one?
I'd generally avoid using staticness and null-checking from your code - create normal classes without singleton wiring by default and layer that aspect on top via the container. Ditto, remove reliance on property injection - ctor injection is always better unless you have no choice
i.e.:
class TemplateManager
{
readonly IRepository<Template> _templateRepository;
public TemplateManager(IRepository<Template> templateRepository)
{
_templateRepository = templateRepository;
}
public ITemplate LoadRoot()
{
return _templateRepository.Retrieve(1); // obviously better logic here.
}
}
class TemplateModule : Module
{
public void Load()
{
Bind<ITemplate>().ToMethod(() => kernel.Get<TemplateManager>().LoadRoot()).InSingletonScope();
}
}
And then I'd question whether TemplateManager should become a ninject provider or be inlined.
As for the actual question... The big question is, how and when do you want to control clearing the cache to force reloading if you decided that the caching should be at session level, not app level due to authorization influences on the template tree? In general, I'd say that should be the Concern of an actual class rather than bound into your DI wiring or hardwired into whether a class is a static class or is a Singleton (as in the design pattern, not the ninject Scope).
My tendency would be to have a TemplateManager class with no static methods, and make that a singleton class in the container. However, to get the root template, consumers should get the TemplateManager injected (via ctor injection) but then say _templateManager.GetRootTemplate() to get the template.
That way, you can:
not have a reliance on fancy ninject providers and/or tie yourself to your container
have no singleton cruft or static methods
have simple caching logic in the TemplateManager
vary the Scoping of the manager without changing all the client code
have it clear that getting the template may or may not be a simple get operation
i.e, I'd manage it like so:
class TemplateManager
{
readonly IRepository<Template> _templateRepository;
public TemplateManager(IRepository<Template> templateRepository)
{
_templateRepository = templateRepository;
}
ITemplate _cachedRootTemplate;
ITemplate FetchRootTemplate()
{
if(_cachedRootTemplate==null)
_cachedRootTemplate = LoadRootTemplate();
return _cachedRootTemplate;
}
ITemplate LoadRoot()
{
return _templateRepository.Retrieve(1); // obviously better logic here.
}
}
register it like so:
class TemplateModule : Module
{
public void Load()
{
Bind<TemplateManager>().ToSelf().InSingletonScope();
}
}
and then consume it like so:
class TemplateConsumer
{
readonly TemplateManager _templateManager;
public TemplateConsumer(TemplateManager templateManager)
{
_templateManager = templateManager;
}
void DoStuff()
{
var rootTempalte = _templateManager.FetchRootTemplate();
Wild speculation: I'd also consider not having a separate IRepository being resolvable in the container (and
presumably having all sorts of ties into units of work). Instead, I'd have the TemplateRepository be a longer-lived thing not coupled to an ORM layer and Unit Of Work. IOW having a repository and a Manager none of which do anything well defined on their own isnt a good sign - the repository should not just be a Table Data Gateway - it should be able to be the place that an Aggregate Root such as Templates gets cached and collated together. But I'd have to know lots more about your code base before slinging out stuff like that without context!