Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Friday, 27 December 2013
( N-Tier )

 

image
Dependency Inversion principle

image
Ahh – just to instantiate this service we need to new up 4 other classes.

Adding a Console Application

putting in a service layer in the form of WebAPI

image
Wiring up the Console app to call our WebAPI service

He likes 1 front end project per sln.

image

https://s3.amazonaws.com/pluralsight-free/meet-the-author/steve-smith-ntier-apps.mp3

  • modular
  • loosely coupled
  • testable
  • better refactoring tools

Data centric ntier architecture

  • most common.. 10 years ago
  • UI
  • BLL..services methods and behaviour
  • DAL.. used to be ado.net code or generated.. or calls to SP’s
  • Disadvantages
    • testing..hard.
    • UI is instantiating BLL directly
    • BLL is newing up DAL
    • or calling static methods..
    • so tightly coupled

Domain centric design

  • DDD book eg ERic Evans
  • Clean code by uncle bob
  • Higher level code doesn’t depend on lower level implementation
  • So not tightly coupled
  • So tests can mock out and isolate

Better code that follows SOLID principles

| | # 
( N-Tier )

Activerecord

image

image
Using PIFriend (Persistence Ignorant) friend which inherts off Friend. 

Friend has to talk to the db…

Repository

Talks about transactions here

[TestClass]
public class EfFriendRepositoryWithTransaction_CreateShould
{
private TransactionScope scope = null;

[TestInitialize]
public virtual void TestInitialize()
{
    scope = new TransactionScope(TransactionScopeOption.RequiresNew,
        new TransactionOptions()
        {
            IsolationLevel = IsolationLevel.ReadUncommitted
        });
}

[TestCleanup]
public virtual void TestCleanup()
{
    if (scope != null)
    {
        scope.Dispose();
        scope = null;
    }
}

[TestMethod]
public void AddRecordTx()
{
    Guid testUserId;
    using (var context = new aspnetdbEntities())
    {
        testUserId = context.aspnet_Membership.First().UserId;
    }

    var friendRepository = new EfFriendRepository();
    var testEmail = Guid.NewGuid().ToString();

    friendRepository.Create(testUserId, testEmail);

    using (var context = new aspnetdbEntities())
    {
        bool friendExists = context.Friends.Any(f => f.UserId == testUserId && f.EmailAddress == testEmail);
        Assert.IsTrue(friendExists);

        //context.DeleteObject(context.Friends.FirstOrDefault(f => f.UserId == testUserId && f.EmailAddress == testEmail));
        //context.SaveChanges();
    }
}

Using a transaction

 

image

ORMs
image
Only repositories should know about entities.  Client objects deal with domain objects.

public IEnumerable<Friend> ListFriendsOfUser(Guid userId)
{
    var context = new aspnetdbEntities();
    return context.Friends
        .Where(f => f.UserId == userId)
        .Select(f => new Friend()
        {
            Id = f.Id,
            EmailAddress = f.EmailAddress
        });
}

In Infrastructure layer – we are mapping the EF Entity Friends to the domain entity Friend with the Linq select statement.

Only core domain types are exposed by the repository.

Automapper

Object to object mapper

namespace PluralSightBook.IntegrationTests.Spikes.Mapping
{
    [TestClass]
    public class RepoMappingTests
    {
        [ClassInitialize]
        public static void TestRunInitialize(TestContext context)
        {
            Mapper.CreateMap<Friends, PluralSightBook.Core.Model.Friend>();
        }

        [TestMethod]
        public void ListFriendsUsingMapper()
        {
            var friendRepository = new MappingFriendRepository();

            var context =new PluralSightBook.Data.PluralSightBookContext();
            var initializer = new TestDbInitializer();
            initializer.Reseed(context);

            var testUserId = context.aspnet_Users.FirstOrDefault().UserId;
            friendRepository.Create(testUserId, "foo@bar.com");
            var result = friendRepository.ListFriendsOfUser(testUserId);

            Assert.IsInstanceOfType(result.FirstOrDefault(), typeof(PluralSightBook.Core.Model.Friend));
        }

Using IntegrationTests folder to spike out Automapper.  Mapping Friends entity to Friend domain object.

public IEnumerable<Core.Model.Friend> ListFriendsOfUser(Guid userId)
{
    var context = new aspnetdbEntities();
    return context.Friends
        .Where(f => f.UserId == userId)
        .ToList()
        .Select(f => Mapper.Map<Friends, PluralSightBook.Core.Model.Friend>(f));
        //.Select(f => new PluralSightBook.Core.Model.Friend()
        //{
        //    Id = f.Id,
        //    EmailAddress = f.EmailAddress
        //});
}

In repository, using automapper to map Friend to Model.Friend.

Code First

Don’t need to map entites to domain objects!

nHibernate

using fluent nHibernate it is just like CodeFirst

Generic Repositories

image

    public class Repository<T> : IRepository<T>
        where T : class
    {
        private readonly DbContext _context;
        protected DbContext context
        {
            get
            {
                return _context;
            }
        }

        public Repository(DbContext context)
        {
            this._context = context;
        }

        public Repository()
        {
            this._context = new PluralSightBookContext();
        }

        public IEnumerable<T> GetAll()
        {
            return this._context.Set<T>();
        }

        public T GetById(int id)
        {
            return this._context.Set<T>().Find(id);
        }

        public IEnumerable<T> Query(Expression<Func<T, bool>> filter)
        {
            return this._context.Set<T>().Where(filter);
        }

        public void Add(T entity)
        {
            this._context.Set<T>().Add(entity);
        }

        public void Remove(T entity)
        {
            this._context.Set<T>().Remove(entity);
        }

        public void Update(T entity)
        {
            this._context.Entry(entity).State = System.Data.EntityState.Modified;
        }

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

A generic repository

He doesn’t like exposing IQueryable though..but leads to problems perhaps with a lot of data.

DI / IoC / StructureMap

| | #