Implementing DI & IoC Pattern in MVC 4 with MEF 2 Attributeless using Conventions with RegistrationBuilder in .NET 4.5 – Part 2

May 17, 2013 17 comments

From my previous article Generically Implementing the Unit of Work & Repository Pattern with Entity Framework in MVC & Simplifying Entity Graphs – Part 1, we covered how to properly setup your project and implement the Unit Of Work and Repository patterns. In this article, we’ll take our solution the next logical progression, which is getting DI (Dependency Injection) & IoC (Inverse of Control) patterns implemented.

DI & IoC will bring many advantages to our solution. a few of them are as follows.

  1. Programming against abstractions and away from our concrete implementations.
  2. Complementing the previous item, allowing us replace or select concrete implementations during run-time.
  3. Giving us an easy way to mock-up certain implementations for quick unit tests.

Now there are many other debatable benefits for DI & IoC, and I’ll let you make you form your own opinions on this topic, however for the purposes of this post, let’s jump into implementation. We will start off, where we left off in our solution, from our previous post.

First we will need to go ahead and get MEF (Managed Extensibility Framework) wired up, we can get a jump start to this by using our MVC MEF library from my blog post found here.

Note: There are two methods MEF will register exports and imports, one by attributes, which most of know about, the second, is by conventions. I’ve searched high and low on how to get MEF working with MVC using MEF Registrations and have absolutely zero luck, so with that being said, more reason to setup our solution using MEF Registrations (convention based) vs. the Attribute approach

With the Mv4.Mef project added and referenced in our Web project, let’s go ahead and wire up the some code in our Web startup. Now, instead of polluting our Global.asax.cs Application_Start() method with all our MEF Registrations and Conventions, let’s follow the MVC pattern, by adding a MefConfig.cs class under the App_Start folder with the rest of the application start-up code resides.

5-17-2013 7-37-59 PM

Web.App_Start.MefConfig.cs


    public static class MefConfig
    {
        public static void RegisterMef()
        {
            // Set up all the Mef conventions for our web assembly
            var registrationBuilder = new RegistrationBuilder();

            registrationBuilder.ForTypesDerivedFrom<Controller>()
                .SetCreationPolicy(CreationPolicy.NonShared).Export();

            registrationBuilder.ForTypesDerivedFrom<ApiController>()
                .SetCreationPolicy(CreationPolicy.NonShared).Export();

            registrationBuilder
                .ForTypesMatching(t =>
                    t.FullName.StartsWith(
                        Assembly
                            .GetExecutingAssembly()
                            .GetName().Name + ".Parts."))
                .SetCreationPolicy(CreationPolicy.NonShared)
                .ExportInterfaces(x => x.IsPublic);

            var aggregateCatalog = new AggregateCatalog();

            aggregateCatalog.Catalogs.Add(
                new AssemblyCatalog(Assembly.GetExecutingAssembly(), registrationBuilder));

            // Set up all the Mef conventions for our repository assembly
            registrationBuilder = new RegistrationBuilder();

            registrationBuilder.ForTypesDerivedFrom<IUnitOfWork>().Export<IUnitOfWork>();

            aggregateCatalog.Catalogs.Add(
                new AssemblyCatalog(typeof(IUnitOfWork).Assembly, registrationBuilder));

            // Set up all the Mef conventions for our data assembly
            registrationBuilder = new RegistrationBuilder();

            registrationBuilder.ForTypesDerivedFrom<IDbContext>().Export<IDbContext>();

            aggregateCatalog.Catalogs.Add(
                new AssemblyCatalog(typeof(IDbContext).Assembly, registrationBuilder));

            // Add all our catalogs with Mef conventions to our container
            MefMvcConfig.RegisterMef(new CompositionContainer(aggregateCatalog));
        }
    }

Now let’s invoke our MEF configuration from the Global.asax.cs Application_Start() method.

Web.Global.asax.cs


namespace Web
{
    public class MvcApplication : HttpApplication
    {
        protected void Application_Start()
        {
            MefConfig.RegisterMef();
            AreaRegistration.RegisterAllAreas();
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
        }
    }
}

So we everything from line 5 to 51 is simply setting up all the import and export mappings from all of our projects or assemblies, I’ll go over some of the conventions we are setting up with the MEF’s RegistrationBuilder.


            registrationBuilder.ForTypesDerivedFrom<Controller>()
                .SetCreationPolicy(CreationPolicy.NonShared).Export();

Her we are saying go ahead and export everything that inherits or is derived from Controller, which means go ahead and add all of our controllers to the Composition Container.


            registrationBuilder.ForTypesDerivedFrom<ApiController>()
                .SetCreationPolicy(CreationPolicy.NonShared).Export();

Here (same principles as the previous item) we are saying go ahead and add all of our Web Api Controllers to the container.


            registrationBuilder
                .ForTypesMatching(t =>
                    t.FullName.StartsWith(
                        Assembly
                            .GetExecutingAssembly()
                            .GetName().Name + ".Parts."))
                .SetCreationPolicy(CreationPolicy.NonShared)
                .ExportInterfaces(x => x.IsPublic);

In this block of code, we are saying go ahead and export everything that implements a public interface as the interface it’s implementing that in the Parts folder in our web project as exampled here http://msdn.microsoft.com/en-us/library/hh708870.aspx.


            registrationBuilder
                .ForTypesDerivedFrom<IUnitOfWork>().Export<IUnitOfWork>();

This is pretty straight forward export anything that is derived from IUnitOfWork as IUnitOfWork. Great, hopefully this sheds some light on how we can setup some conventions for export and import mapping for our Composition Container.

Now let’s revisit to our CustomerController we were working on previously.

Before:


    public class CustomerController : Controller
    {
        public ActionResult Index(int? page)
        {
            var pageNumber = page ?? 1;
            const int pageSize = 20;

            var unitOfWork = new UnitOfWork();

            int totalCustomerCount;

            var customers =
                unitOfWork.Repository<Customer>()
                    .Query()
                    .Include(i => i.CustomerDemographics)
                    .OrderBy(q => q
                        .OrderBy(c => c.ContactName)
                        .ThenBy(c => c.CompanyName))
                    .Filter(q => q.ContactName != null)
                    .GetPage(pageNumber, pageSize, out totalCustomerCount);

            ViewBag.Customers = new StaticPagedList<Customer>(
                customers, pageNumber, pageSize, totalCustomerCount);

            unitOfWork.Save();

            return View();
        }
    }

Now, lets inject all our dependencies that the CustomerController has using one of MEF’s supported Import methods, Constructor Injection.

After:


    public class CustomerController : Controller
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ICustomerService _customerService;

        public CustomerController(
            IUnitOfWork unitOfWork, 
            ICustomerService customerService)
        {
            _unitOfWork = unitOfWork;
            _customerService = customerService;
        }

        public IUnitOfWork UnitOfWork { get; set; }

        public ActionResult Index(int? page)
        {
            var pageNumber = page ?? 1;
            const int pageSize = 20;

            int totalCustomerCount;

            var customers =
                _unitOfWork.Repository<Customer>()
                    .Query()
                    .Include(i => i.CustomerDemographics)
                    .OrderBy(q => q
                        .OrderBy(c => c.ContactName)
                        .ThenBy(c => c.CompanyName))
                    .Filter(q => q.ContactName != null)
                    .GetPage(pageNumber, pageSize, out totalCustomerCount);

            ViewBag.Customers = new StaticPagedList<Customer>(
                customers, pageNumber, pageSize, totalCustomerCount);

            return View();
        }
    }

Let’s debug and make sure that the IUnitOfWork is getting injected with Constructor Injection from MEF by putting int two breakpoints, first one in the MefMvcControllerFactory so we can take a peek at the Catalog in our Composition Container and the second one in the CustomerController itself.

5-17-2013 5-33-56 PM

Now here we see that all of our previously wired up MEF conventions are valid, we see all of our Controllers, Services, UnitOfWork and NorthwindContext in our CompositionContainer, great! Now for a sanity check, let’s take a look at our CustomerController to ensure that we are actually getting injected now that we validated our container.

5-17-2013 5-43-22 PM

Now let’s just take a quick look at our UnitOfWork and CustomerService objects and notice how there are not attributes decorated anywhere and that they are indeed being added to our CompositionContainer by the conventions we setup earlier with the RegistrationBuilder.

Repostiory.UnitOfWork


namespace Repository
{
    public class UnitOfWork : IUnitOfWork
    {
        private readonly IDbContext _context;

        private bool _disposed;
        private Hashtable _repositories;

        public UnitOfWork(IDbContext context)
        {
            _context = context;
            InstanceId = Guid.NewGuid();
        }

        public Guid InstanceId { get; set; }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        public void Save()
        {
            _context.SaveChanges();
        }

        public virtual void Dispose(bool disposing)
        {
            if (!_disposed)
                if (disposing)
                    _context.Dispose();

            _disposed = true;
        }

        public IRepository<T> Repository<T>() where T : class
        {
            if (_repositories == null)
                _repositories = new Hashtable();

            var type = typeof (T).Name;

            if (!_repositories.ContainsKey(type))
            {
                var repositoryType = typeof (Repository<>);

                var repositoryInstance = 
                    Activator.CreateInstance(repositoryType
                            .MakeGenericType(typeof (T)), _context);
                
                _repositories.Add(type, repositoryInstance);
            }

            return (IRepository<T>) _repositories[type];
        }
    }
}

Web.Parts.CustomerService


namespace Web.Parts
{
    public class CustomerService : ICustomerService
    {
        private readonly IUnitOfWork _unitOfWork;

        public CustomerService(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        public void UpdateWithAddressValidation(Customer customer)
        {
                // Example stubbed method, for same UnitOfWork 
                //instance injetction test with page request scoped
        }
    }
}

Awesome, our CustomerController is being handled and instantiated by MEF, therefore it is also handling all the Dependency Injection in the CustomerController e.g. IUnitOfWork and the ICustomerService.

5-17-2013 5-43-22 PM

Now, one very important note, notice that I’ve added a property the UnitOfWork named InstanceId of type Guid. I’ve deliberately drilled down the UnitOfWork.InstanceId in both the UnitOfWork and CustomerService objects in the debug mode screenshot, so that we can see that they are both indeed the same instance. This is very important when using MEF with MVC, that by default, the Scope of the items life cycle are per page request, and will be disposed of after the request has completed. For scenarios where we deliberately want an instance to live for the entire life cycle of the application we can set CreationPolicy for that export to be shared.

Happy Coding..! :)

Download sample application:

Self managed HTTP scoped IUnitOfWork, IDbContext using HttpContext.Current.Items:

https://skydrive.live.com/redir?resid=949A1C97C2A17906!5107&authkey=!AIfx5T8CZ5LlxAs.

HTTP scoped using System.ComponentModel.Composition.Web.Mvc Preview 5, which I have upgraded to target .NET 4.5.

https://skydrive.live.com/redir?resid=949A1C97C2A17906!5108&authkey=!ACJE75BhOdiDSwI

About these ads

Generically Implementing the Unit of Work & Repository Pattern with Entity Framework in MVC & Simplifying Entity Graphs – Part 1

May 11, 2013 8 comments

First off let’s elegantly setup our solution, and prep it for real world development. We have our solution broken up into four different projects, now let’s talk about the “why?”.

5-8-2013 9-08-17 PM

Data Project (Data Access Layer)

This is where all of our ORM tooling related objects reside. In our case the EF (Entity Framework 6.0 Alpha 3) DataContext, Mappings, Migrations, etc. This give is nice separation, control and isolation of where any persistence related objects live. If ever, one day we need to change the tool of choice, or even upgrade, there’s only one layer or project to do this in, the Data project.

5-8-2013 10-08-26 PM

Entities Project (Domain Layer)
The Entities project is where all of our POCO (Plan Old C# Objects) objects will live. POCO’s should be very ignorant objects that pretty much have nothing in them but the structure of your data. With that being said, typically anything outside our Repository layer e.g. presentation layer (MVC), services layer (will cover in next post) should be completely ignorant to any persistence tool or technology e.g. NHibernate, eXpressPersistent, OpenAccess, EF (our case), etc.

5-8-2013 10-09-31 PM

Repository (Layer)
This is where our UoW (Unit of Work) pattern will be implemented as well as our Repository implementation. Our UoW implementation will handle most of our usual CRUD activities.

Two important objectives we will try to with our UoW pattern implementation are:

  1. Abstract away the ORM tool, in our case EF.
  2. Ensuring that all interactions with the database are happening under one DbContext instance per page request.

Obviously there are many other benefits, such giving us the ability to implement different variations of our UoW, potentially wire up to different types of repositories. For purposes of this article, we’ll stake focus on our two primary objectives, and I’ll cover the other benefits in later posts.

Web Project (Presentation Layer)
This is our presentation layer, for the purposes of the blog, we will use MVC (ASP.NET MVC 4). Again, this project should not have any dependent code on EF assembly, therefore that should not be any references to the EF assembly, it should only reference our Repository project for data access.

Refactoring the NorthwindContext for an Abstracted and Cleaner Implementation

Now that we’ve gone over the solution and it’s projects, let’s do a little bit of refactoring and cleaning up with our EF code.

Data.NorthwindDataContext.cs

Before:


    public class NorthwindContext : DbContext
    {
        static NorthwindContext()
        {
            Database.SetInitializer<NorthwindContext>(null);
        }

        public NorthwindContext()
            : base("Name=NorthwindContext")
        {
        }

        public DbSet Category Categories { get; set; }
        public DbSet CustomerDemographic CustomerDemographics { get; set; }
        public DbSet Customer Customers { get; set; }
        public DbSet Employee Employees { get; set; }
        public DbSet OrderDetail Order_Details { get; set; }
        public DbSet Order Orders { get; set; }
        public DbSet Product Products { get; set; }
        public DbSet Region Regions { get; set; }
        public DbSet Shipper Shippers { get; set; }
        public DbSet Supplier Suppliers { get; set; }
        public DbSet Territory Territories { get; set; }
        public DbSet Invoice Invoices { get; set; }


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new CategoryMap());
            modelBuilder.Configurations.Add(new CustomerDemographicMap());
            modelBuilder.Configurations.Add(new CustomerMap());
            modelBuilder.Configurations.Add(new EmployeeMap());
            modelBuilder.Configurations.Add(new Order_DetailMap());
            modelBuilder.Configurations.Add(new OrderMap());
            modelBuilder.Configurations.Add(new ProductMap());
            modelBuilder.Configurations.Add(new RegionMap());
            modelBuilder.Configurations.Add(new ShipperMap());
            modelBuilder.Configurations.Add(new SupplierMap());
            modelBuilder.Configurations.Add(new TerritoryMap());
            modelBuilder.Configurations.Add(new InvoiceMap());
        }
    }

After:

     public class NorthwindContext : DbContext, IDbContext
    {
        static NorthwindContext()
        {
            Database.SetInitializer<NorthwindContext>(null);
        }

        public NorthwindContext()
            : base("Name=NorthwindContext")
        {
        }

        public new IDbSet<T> Set<T>() where T : class
        {
            return base.Set<T>();
        }

        public override int SaveChanges()
        {
            this.ApplyStateChanges();
            return base.SaveChanges();
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new CategoryMap());
            modelBuilder.Configurations.Add(new CustomerDemographicMap());
            modelBuilder.Configurations.Add(new CustomerMap());
            modelBuilder.Configurations.Add(new EmployeeMap());
            modelBuilder.Configurations.Add(new Order_DetailMap());
            modelBuilder.Configurations.Add(new OrderMap());
            modelBuilder.Configurations.Add(new ProductMap());
            modelBuilder.Configurations.Add(new RegionMap());
            modelBuilder.Configurations.Add(new ShipperMap());
            modelBuilder.Configurations.Add(new SupplierMap());
            modelBuilder.Configurations.Add(new TerritoryMap());
            modelBuilder.Configurations.Add(new InvoiceMap());
        }
    }

We can see that our DbContext is now much cleaner, and that it implements IDbContext. IDbContext will be the abstraction we will be working with when interacting with it’s concrete implementation, NorthwindContext.

Best Practice, Coding Against Abstractions or Interfaces

Abstractions serve as a nice flexibility point later, allowing us to implement different variations of the abstraction (interface). This will be very useful later when we implement DI (Dependency Injection and IoC (Inverse of Control) patterns. Coding to an abstraction will also help us easily create unit test, allowing us to inject faked or mocked instances as well. If your a bit unclear on how this helps set stage for DI, IoC and Unit Testing, no worries, I’ll cover these topics in the next post.

Data.IDbContext.cs


namespace Data
{
    public interface IDbContext
    {
        IDbSet<T> Set<T>() where T : class;
        int SaveChanges();
        DbEntityEntry Entry(object o);
        void Dispose();
    }
}

Now, let’s take take a look at what’s all in our Repository project.

5-10-2013 7-02-10 PM

IUnitOfWork This is simply the contract or abstraction that we will be working with, when interacting with it’s concrete implementation which will be UnitOfWork object.

Repository.IUnitOfwork.cs



namespace Repository
{
    public interface IUnitOfWork
    {
        void Dispose();
        void Save();
        void Dispose(bool disposing);
        IRepository<T> Repository<T>() where T : class;
    }
}

Concrete Implementation of IUnitOfWork.cs


namespace Repository
{
    public class UnitOfWork : IUnitOfWork
    {
        private readonly IDbContext _context;

        private bool _disposed;
        private Hashtable _repositories;

        public UnitOfWork(IDbContext context)
        {
            _context = context;
        }

        public UnitOfWork()
        {
            _context = new NorthwindContext();
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        public void Save()
        {
            _context.SaveChanges();
        }

        public virtual void Dispose(bool disposing)
        {
            if (!_disposed)
                if (disposing)
                    _context.Dispose();

            _disposed = true;
        }

        public IRepository<T> Repository<T>() where T : class
        {
            if (_repositories == null)
                _repositories = new Hashtable();

            var type = typeof (T).Name;

            if (!_repositories.ContainsKey(type))
            {
                var repositoryType = typeof (Repository<>);

                var repositoryInstance = 
                    Activator.CreateInstance(repositoryType
                            .MakeGenericType(typeof (T)), _context);
                
                _repositories.Add(type, repositoryInstance);
            }

            return (IRepository<T>) _repositories[type];
        }
    }
}

Let’s take a look at our IRepository Repository() method here in our UnitOfWork implementation. Here we are storing all the activated instances of repositories for each and every requests. One there is a request for a given repository we will first check to see if our Hashtable (container to hold all of our activated repository instances) has been created, if not, will go ahead and create our container. Next, we’ll scan our container to see if the requested repository instance has already been created, if it has, then will return it, if it hasn’t, we will activate the requested repository instance, store it in our container, and then return it. If it helps, you can think of this as lazy loading our repository instances, meaning we are only creating repository instances on demand, this allows us to only create the repository instances needed for a given web request. Last but not least, notice here how we are following best practices mentioned earlier, we are not return the concrete implementation for the Repository, but the abstraction, IRepository.

Repository.IRepository.cs


namespace Repository
{
    public interface IRepository<TEntity> where TEntity : class
    {
        TEntity FindById(object id);
        void InsertGraph(TEntity entity);
        void Update(TEntity entity);
        void Delete(object id);
        void Delete(TEntity entity);
        void Insert(TEntity entity);
        RepositoryQuery<TEntity> Query();
    }
}


Repository.Repository.cs


    public class Repository<TEntity> :
        IRepository<TEntity> where TEntity : class
    {
        internal IDbContext Context;
        internal IDbSet<TEntity> DbSet;

        public Repository(IDbContext context)
        {
            Context = context;
            DbSet = context.Set<TEntity>();
        }

        public virtual TEntity FindById(object id)
        {
            return DbSet.Find(id);
        }

        public virtual void InsertGraph(TEntity entity)
        {
            DbSet.Add(entity);
        }

        public virtual void Update(TEntity entity)
        {
            DbSet.Attach(entity);
        }

        public virtual void Delete(object id)
        {
            var entity = DbSet.Find(id);
            Delete(entity);
        }

        public virtual void Delete(TEntity entity)
        {
            DbSet.Attach(entity);
            DbSet.Remove(entity);
        }

        public virtual void Insert(TEntity entity)
        {
            DbSet.Attach(entity);
        }

        public virtual RepositoryQuery<TEntity> Query()
        {
            var repositoryGetFluentHelper =
                new RepositoryQuery<TEntity>(this);

            return repositoryGetFluentHelper;
        }

        internal IEnumerable<TEntity> Get(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>,
                IOrderedQueryable<TEntity>> orderBy = null,
            List<Expression<Func<TEntity, object>>>
                includeProperties = null,
            int? page = null,
            int? pageSize = null)
        {
            IQueryable<TEntity> query = DbSet;
            
            if (includeProperties != null)
                includeProperties.ForEach(i => query.Include(i));

            if (filter != null)
                query = query.Where(filter);

            if (orderBy != null)
                query = orderBy(query);

            if (page != null && pageSize != null)
                query = query
                    .Skip((page.Value - 1)*pageSize.Value)
                    .Take(pageSize.Value);


            return query.ToList();
        }
    }

Our generic implementation for Repository allows us to have have all our basic heavy lifting of a Repository out of the box for any one of our Entities. All we have to do is request for the Repository of interest by passing in the Entity e.g.

UnitOfWork.Repository<Customer>

will give us the Customer Repository with all our out of the box plumbing available.

Let’s take a quick look at our Get method in the Repository implementation.


        internal IEnumerable<TEntity> Get(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>,
                IOrderedQueryable<TEntity>> orderBy = null,
            List<Expression<Func<TEntity, object>>>
                includeProperties = null,
            int? page = null,
            int? pageSize = null)
        {
            IQueryable<TEntity> query = DbSet;
            
            if (includeProperties != null)
                includeProperties.ForEach(i => query.Include(i));

            if (filter != null)
                query = query.Where(filter);

            if (orderBy != null)
                query = orderBy(query);

            if (page != null && pageSize != null)
                query = query
                    .Skip((page.Value - 1)*pageSize.Value)
                    .Take(pageSize.Value);


            return query.ToList();
        }

The Get method here, handles fetching data. It handles querying the data supporting a filtering, ordering, paging, and eager loading of child types, so that we can make one round trip and eager load the entity graph.

We notice here that the method is marked “internal”, this is because we only want the Get method here to be accessible to objects with the same assembly, Repository.dll. We will expose the Get method via the Query method and return the RepositoryQuery object to provide a fluent “ish” api, so that’s its a bit more easy and intuitive for our developers when querying with our Repository layer. Note, only methods in our RepositoryQuery will actually invoke the internal Get method, again, which is why we went ahead and marked the Get method internal.

Repository.RepositoryQuery.cs (our fluent api helper class)


    public sealed class RepositoryQuery<TEntity> where TEntity : class
    {
        private readonly List<Expression<Func<TEntity, object>>> 
            _includeProperties;

        private readonly Repository<TEntity> _repository;
        private Expression<Func<TEntity, bool>> _filter;
        private Func<IQueryable<TEntity>, 
            IOrderedQueryable<TEntity>> _orderByQuerable;
        private int? _page;
        private int? _pageSize;

        public RepositoryQuery(Repository<TEntity> repository)
        {
            _repository = repository;
            _includeProperties = 
                new List<Expression<Func<TEntity, object>>>();
        }

        public RepositoryQuery<TEntity> Filter(
            Expression<Func<TEntity, bool>> filter)
        {
            _filter = filter;
            return this;
        }

        public RepositoryQuery<TEntity> OrderBy(
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy)
        {
            _orderByQuerable = orderBy;
            return this;
        }

        public RepositoryQuery<TEntity> Include(
            Expression<Func<TEntity, object>> expression)
        {
            _includeProperties.Add(expression);
            return this;
        }

        public IEnumerable<TEntity> GetPage(
            int page, int pageSize, out int totalCount)
        {
            _page = page;
            _pageSize = pageSize;
            totalCount = _repository.Get(_filter).Count();

            return _repository.Get(
                _filter, 
                _orderByQuerable, _includeProperties, _page, _pageSize);
        }

        public IEnumerable<TEntity> Get()
        {
            return _repository.Get(
                _filter, 
                _orderByQuerable, _includeProperties, _page, _pageSize);
        }
    }

Addressing IRepository<TEntity> Extensibility

Well, what happens if we need extra methods a specific Repository? Meaning, how do we address “extensiblility” in our Repository? No problem, we have a couple of options here, we can simply inherit a Repository and add your own methods to it, or what I prefer, create extension methods e.g. extending IRepository (with some pseudo code for validating an address with UPS).

Repository.CustomerRepository.cs

    /// <summary>
    /// Extending the IRepository<Customer>
    /// </summary>
    public static class CustomerRepository
    {
        public static decimal GetCustomerOrderTotalByYear(
            this IRepository<Customer> customerRepository, 
            int customerId, int year)
        {
            return customerRepository
                .FindById(customerId)
                .Orders.SelectMany(o => o.OrderDetails)
                .Select(o => o.Quantity*o.UnitPrice).Sum();
        }

    /// <summary>
    /// TODO:
    /// This should really live in the Services project (Business Layer), 
    /// however, we'll leave it here for now as an example, and migrate
    /// this in the next post.
    /// </summary>
        public static void AddCustomerWithAddressValidation(
            this IRepository<Customer> customerRepository, Customer customer)
        {
            USPSManager m = new USPSManager("YOUR_USER_ID", true);
            Address a = new Address();
            a.Address1 = customer.Address;
            a.City = customer.City;

            Address validatedAddress = m.ValidateAddress(a);

            if (validatedAddress != null)
            customerRepository.InsertGraph(customer);
        }
    }

Great, now that we have our project nicely structured with the our generic implementation of the Unit of Work and Repository Pattern, let’s see how we can leverage this by wiring up a simple controller to show a list of customers.

To help us with this go ahead and NuGet the PagedList for MVC so we easily create a view with a paged grid.

5-10-2013 6-22-37 PM

Let’s create a CustomerController Index Action load a paged list of customers to hydrate a grid.


    public class CustomerController : Controller
    {
        public ActionResult Index(int? page)
        {
            var pageNumber = page ?? 1;
            const int pageSize = 20;

            var unitOfWork = new UnitOfWork();

            int totalCustomerCount;

            var customers =
                unitOfWork.Repository<Customer>()
                    .Query()
                    .Include(i => i.CustomerDemographics)
                    .OrderBy(q => q
                        .OrderBy(c => c.ContactName)
                        .ThenBy(c => c.CompanyName))
                    .Filter(q => q.ContactName != null)
                    .GetPage(pageNumber, pageSize, out totalCustomerCount);

            ViewBag.Customers = new StaticPagedList<Customer>(
                customers, pageNumber, pageSize, totalCustomerCount);

            unitOfWork.Save();

            return View();
        }
    }

Next, let’s wire up the Index.cshtml view for our CustomerController Index Action.


@{
    ViewBag.Title = "Customers";
}

@using PagedList.Mvc;
@using PagedList;

<h2>Customers</h2>

<link href="/Content/PagedList.css" rel="stylesheet" type="text/css" />

<h2>List of Customers</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table style="width: 100%; padding: 10px;">
    <tr style="background-color: lightgray; padding: 10px;">
        <th>#</th>
        <th>Company
        </th>
        <th>Name
        </th>
        <th>Title
        </th>
        <th>Order Date
        </th>
    </tr>

    @foreach (var item in ViewBag.Customers)
    {
        <tr>
            <td>
                @Html.ActionLink(
                    "Edit", "Edit", new { id = item.CustomerID }) |

                @Html.ActionLink(
                    "Details", "Details", new { id = item.CustomerID }) |

                @Html.ActionLink(
                    "Delete", "Delete", new { id = item.CustomerID })
            </td>
            <td>
                @item.CompanyName
            </td>
            <td>
                @item.ContactName
            </td>
            <td>
                @item.ContactTitle
            </td>
            <td>
                @if (item.Orders.Count > 1)
                {
                    @item.Orders[1].OrderDate.ToShortDateString()
                }
            </td>
        </tr>
    }


    <tr>
        <td colspan="9">
            @Html.PagedListPager(
                (IPagedList)ViewBag.Customers, page => 
                    Url.Action("Index", new { page }))
        </td>
    </tr>

</table>


Go ahead and run our project to see our paged customers grid.

5-10-2013 6-46-30 PM

Abstracting the Complexity when Dealing with Entity Graphs

Another item I wanted to go over was insert and updating graphs with our Repository pattern. There are four use cases for inserting graphs, they are as follows.

5-10-2013 7-34-28 PM

To abstract the complexity and EF experience required, and how the DbContext manages graphs e.g to know to set the root entity state and how it affects other entities in the graph (e.g. updating the root entity in the graph, and existing entities in the graph are to be updated or deleted) we added a interface IOjectState that all of our entities will implement.

Entities.IObjectState.cs


namespace Data
{
    public interface IObjectState
    {
        ObjectState State { get; set; }
    }
}

Entities.ObjectState.cs (enum)


namespace Data
{
    public enum ObjectState
    {
        Unchanged,
        Added,
        Modified,
        Deleted
    }
}

These two classes will allow our development team to explicitly set the state of each of the entities in the graph when inserting or updating a graph. To make use of the classes we’ll need to extend the DbContext with a few methods, we’ll do this by creating extension methods.

Data.DbContextExtension.cs


    public static class DbContextExtension
    {
        public static void ApplyStateChanges(this DbContext dbContext)
        {
            foreach (var dbEntityEntry in dbContext.ChangeTracker.Entries())
            {
                var entityState = dbEntityEntry.Entity as IObjectState;
                if (entityState == null)
                    throw new InvalidCastException(
                        "All entites must implement " +
                        "the IObjectState interface, this interface " +
                        "must be implemented so each entites state" +
                        "can explicitely determined when updating graphs.");

                dbEntityEntry.State = ConvertState(entityState.State);
            }
        }

        private static EntityState ConvertState(ObjectState state)
        {
            switch (state)
            {
                case ObjectState.Added:
                    return EntityState.Added;
                case ObjectState.Modified:
                    return EntityState.Modified;
                case ObjectState.Deleted:
                    return EntityState.Deleted;
                default:
                    return EntityState.Unchanged;
            }
        }
    }

Now we will override the SaveChanges in our NorthwindContext to invoke the ApplyStateChanges method to synchronize our ObjectSate with EF’s EntityState, so that the context will know how to deal with each and every entity when dealing with entity graphs.

Data.NorthwindContext.SaveChanges()


        public override int SaveChanges()
        {
            this.ApplyStateChanges();
            return base.SaveChanges();
        }


Now when inserting, updating you can explicitly set the entities state, especially useful when dealing with graphs. This abstracts the skill-set of a developer using our Repository of having to know the what, when and how to set the state of entities in the graph in order for the context to update the graph and persist the graph correctly. Let’s take a look at an example of updating an existing Order and adding an OrderDetail item with an entity graph. Both these actions, are will be executed on the same graph, however notice that the action is different for both of the entity’s, one is updating and the other is adding, however we will only be invoking one method (IRepository.Update(TEntity entity) from our IRepository in one transaction.

So we’ll demonstrate and prove out updating an entity graph with our UnitOfWork implementation in these steps.

Code Snippet from LinqPad, notice how we are explicitly setting each of the entities state in the entity graph.


var unitOfWork = new UnitOfWork(this);

var orderId = 10253;

unitOfWork
	.Repository<Order>()
	.Query()
	.Include(t =&gt; t.Customer)
	.Filter(t=&gt;t.OrderID == orderId)
	.Get().Dump();

var order = unitOfWork
	.Repository<Order>()
	.FindById(orderId);

unitOfWork
	.Repository<OrderDetail>()
	.Query()
	.Filter(t => t.OrderID == orderId)
	.Get().Dump();

order.ShipName = "Long Le";
order.State = ObjectState.Modified;

order.OrderDetails.Add(
	new OrderDetail{
		ProductID = 2,
		UnitPrice = 10,
		Quantity = 2,
		Discount = 1,
		State = ObjectState.Added
	}
);


unitOfWork.Repository<Order>()
	.Update(order);

unitOfWork.Save();

new UnitOfWork(this)
	.Repository<Order>()
	.Query()
	.Include(t => t.Customer)
	.Filter(t => t.OrderID == orderId)
	.Get().Dump();
	
new UnitOfWork(this)
	.Repository<OrderDetail>()
	.Query()
	.Filter(t => t.OrderID == orderId)
	.Get().Dump();
		

Entity Graph Update Scenario

  1. Query the Order table, make note of the ShipName value.
  2. Query the OrderDetail table, make not there are only three (3) items, that belong to the same Order.
  3. Update the ShipName value in the Order.
  4. Add an OrderDetail to the Order.

5-11-2013 4-13-23 PM

(click image to enlarge)

Presto, we were able to successfully update an existing Order and add a new OrderDetail via an entity graph with one transaction using one method. Now, we can absolutely do this using EF out of the box, however, our goal here is was to abstract the complexity and skill set required from a developer in regards to EF specially how do deal with the DbContext in order to make this happen as well as obviously still support working with graphs through our IRepository implementation.

There you have it, and extensible genericized implementation of the UoW and Repository pattern with EF in MVC. In the next blog post, we’ll add DI & IoC to this solution and introduce the Services layer, this layer will house all of our business logic and rules. We will also implement the Services layer in a way, where we don’t violate our Unit of Work pattern, meaning all the work done in our Repository and Services are executed under one single instance the DbContext per page request.

Happy Coding..! :)

Download sample:
https://skydrive.live.com/redir?resid=949A1C97C2A17906!4883&authkey=!AKdI0n7f55pvQf0

System.Data.ProviderIncompatibleException Exception with Entity Framework Power Tools Beta 2 and Beta 3

February 5, 2013 2 comments

Got stuck on this last night, when using Entity Framework Power Tools Beta 3, note: exception also happens in Beta 2 (http://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d) to generate our POCO’s with Entity Framework 5.

Exception:

System.Data.ProviderIncompatibleException: The provider did not return a ProviderManifestToken string. —> System.InvalidOperationException: This operation requires a connection to the ‘master’ database. Unable to create a connection to the ‘master’ database because the original database connection has been opened and credentials have been removed from the connection string. Supply an unopened connection. —> System.Data.SqlClient.SqlException: Login failed for user ‘blah’.

2-5-2013 6-31-42 PM

After falling in the rabbit hole of thinking it was a security issue and tweaking security in SSMS, well security wasn’t the issue, as long as the same SQL Account had rights to the master database, which it already did.

Solution: When you use the Entity Framework Power Tools, you have to check “Save Password” under “Connection Properties” and set “Persist Security Info” to true under “Advanced Properties. if you are using SQL Server Authentication. The tool is just using the standard SQL authentication dialog box, which has this checkbox, however it doesn’t save any of your credential information anywhere, so don’t expect anything to be pre-filled the next time you run the tool and get prompt for credentials.

  • Connection Properties

    2-5-2013 6-25-24 PM
  • Advanced Properties

    2-6-2013 11-39-07 AM

Why? Well when you run Entity Framework Power Tools to generate your POCO’s/data layer, it needs to access additional schema meta-data in your master database for the target database you are trying to generate for. This is obviously a bug, however if you don’t check “Save Password” then it doesn’t keep the password around when it authenticates with the master database for the schema or other related info it needs and therefore this exception. If you continue reading the stack trace, you will see that it states:

Unable to create a connection to the ‘master’ database because the original database connection has been opened and credentials have been removed from the connection string.

I googled and googled with no luck, and after fortunately finding out how to get around this, well hence this blog post. So for those that need to generate your model against a database that’s already in production with CodeFirst not being a viable solution, and getting this exception, here you go.

Happy Coding! :)

Categories: Uncategorized

I <3 my new Macbook Pro Retina with Crane Stand Pro

February 5, 2013 9 comments

Being that I have the absolute worse neck, shoulders, and upper back problems; I’ve been relentlessly searching for a “real” notebook stand for my MacBook Pro Retina. I was primarily looking for one where I could adjust the height to where the top of my notebook’s screen was eye level to be ergonomic compliant (http://www.osha.gov/SLTC/etools/computerworkstations/components_monitors.html). I finally found the Crane Stand Pro from Crane Hardware (http://www.cranehardware.com/product_info.php/products_id/31).

WP_20130205_005 WP_20130205_003

WP_20130205_006

Note: Can’t see my screen in the 1st picture because of my 3M Privacy Filter for MacBook Pro Retina (http://store.apple.com/us/product/HA743ZM/A/3m-15-privacy-filter-for-macbook-pro-with-retina-display), which also works great by the way.

It’s also great because my entire Natural Ergonomic Desktop 7000 (http://www.microsoft.com/hardware/en-us/p/natural-ergonomic-desktop-7000/WTA-00001#details) keyboard can fit under it. This is extremely important for the coders out there, since doing so allows you to minimize the distance from your eyes to the screen, pretty much keeping the same distance from the screen to your eyes as if you weren’t using a stand. Being that I am using a MacBook Pro Retina with a resolution of 2880×1800, this is uberly important, so that I can still see my code while working within Visual Studio. This was also after already trying out the following stands:

Last but not least another great quality of this stand is that it has two points of adjustment, as well as one for the viewing angle.

Anyhow, this stand comes high recommended for developers that are coding on their laptops in in an environment where you might not be at home and don’t have your big screens, in my case, when I’m at the office.

Happy Coding…! :)

Visual Studio 2012 Coded UI Testing (CUIT) Cross Browser in Action Video with IE (Internet Explorer), Firefox, and Chrome

December 19, 2012 2 comments

We’ve been having the need to automate some system test and at the same time wanted to stay within the Microsoft space in terms of our ALM ecosystem. Well, with the new release of the new Coded UI Engine integration with Selenium’s WebDriver, this is now possible!

Quick demo of Visual Studio 2012 Coded UI Test in action (playback mode):



Note: This test were recorded in IE and the code (Search Properties and Search Filters) search criteria was modified in the UIMap to be able to run across all three (3) browsers.

Received my Kendo UI T-Shirt and new Nokia Lumia 920 Windows Phone 8 Today!

November 8, 2012 5 comments

What an awesome Thursday, received my new Kendo UI t-shirt and my new AT&T Nokia Lumia 920 Windows Phone 8 package all in the same day…! Is this the best Thursday or what…?! :)

Time to retire my HTC Titan I Windows 7 Phone, sayonara… If time permits I may due a blog review on the phone, so far it’s the sexiest thing ever, and I must say first impression the screen display does look better than my colleague’s iPhone 5.

Thanks Kendo UI for dev appreciation and shirt, and to AT&T for shipping the phone overnight and getting it to me a day before the official release.

Image

 

Adding Dependency Injection to your ASP.NET MVC Twilio app using MEF (Managed Extensibility Framework)

November 7, 2012 Leave a comment

Adding Dependency Injection to your ASP.NET MVC Twilio app using MEF (Managed Extensibility Framework)

http://www.twilio.com/blog/2012/11/adding-dependency-injection-to-your-asp-net-mvc-twilio-app-using-mef.html

Thanks for the Reblog Twilio!

Follow

Get every new post delivered to your Inbox.

Join 125 other followers

%d bloggers like this: