5
\$\begingroup\$

I am not sure what I am doing is right or not and am looking for experienced opinions.

Soluton Explorer window

Entity Example

namespace Entities.Shop
{
    public class Shop
    {
        public virtual int ShopId { get; set; }
        public virtual string ShopName { get; set; }
        public virtual IList<ShopScore> ShopScores { get; set; }
        public virtual IList<ShopPromotion> ShopPromotions { get; set; }

        public virtual IList<Entities.Menu.Menu> Menus { get; set; }

        public virtual Address.Address Address { get; set; }

        public virtual IList<DeliveryDistrict> DeliveryDistricts { get; set; }
        public virtual IList<Payment.PaymentMethod> PaymentMethods { get; set; }
        public virtual IList<WorkHour> WorkHours { get; set; }

        public virtual int Status { get; set; }
        public virtual int Activity { get; set; }
        public virtual int Available { get; set; }
    }

    public class ShopScore
    {
        public virtual int ShopScoreId { get; set; }
        public virtual int ShopScoreTypeId { get; set; }
        public virtual int Score { get; set; }
    }

    public class ShopScoreType
    {
        public virtual int ShopScoreTypeId { get; set; }
        public virtual string ShopScoreTypeName { get; set; }
    }

    public class ShopPromotion
    {
        public virtual int ShopPromotionId { get; set; }
        public virtual int ShopPromotionTypeId { get; set; }
    }

    public class ShopPromotionType
    {
        public virtual int ShopScoreTypeId { get; set; }
        public virtual string ShopScoreTypeName { get; set; }
    }

    public class DeliveryDistrict
    {
        public virtual int DeliveryDistrictId { get; set; }
        public virtual Location.District District { get; set; }
        public virtual int MinimumPaymentAmount { get; set; }
    }

    public class WorkHour
    {
        public virtual int WorkHourId { get; set; }
        public virtual int Day { get; set; }
        public virtual string OpenAt { get; set; }
        public virtual string CloseAt { get; set; }
    }
}

Business Layer READ Example

    namespace BL.Shop
    {
        public class READ
        {
            public static IList<Entities.Shop.Shop> All()
            {
                return DAL.Shop.READ.All();
            }

            public static IList<Entities.Shop.Shop> ShopList(int CountryId, int CityId, int DistrictId,
                int MinimumTotalScore, List<Entities.Cuisine.Cuisine> Cuisines, int MinimumPaymentAmount, int PaymentMethodId)
            {
                return DAL.Shop.READ.ShopList(CountryId, CityId, DistrictId, MinimumTotalScore, Cuisines, MinimumPaymentAmount, PaymentMethodId);
            }
        }
    }

Data Access Layer (repository) READ Example

namespace DAL.Shop
{
    public class READ
    {
        public static IList<Entities.Shop.Shop> All()
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                IList<Entities.Shop.Shop> stores = session.CreateCriteria(typeof(Entities.Shop.Shop)).List<Entities.Shop.Shop>();

                return stores;
            }
        }

        public static IList<Entities.Shop.Shop> ShopList(int CountryId, int CityId, int DistrictId,
            int MinimumTotalScore, List<Entities.Cuisine.Cuisine> Cuisines, int MinimumPaymentAmount, int PaymentMethodId)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                IList<Entities.Shop.Shop> stores = session.Query<Entities.Shop.Shop>()

                    .Where(C => C.Address.Country.CountryId == CountryId)
                    .Where(C => C.Address.City.CityId == CityId)
                    .Where(C => C.Address.District.DistrictId == DistrictId)

                    .Where(dd => dd.DeliveryDistricts.Any(d => d.District.DistrictId == DistrictId && d.MinimumPaymentAmount <= MinimumPaymentAmount))
                    .Where(p => p.PaymentMethods.Any(pm => pm.PaymentMethodId == PaymentMethodId))
                    //.Where(s => s.ShopScores.Sum(r => r.Score) >= MinimumTotalScore)
                    .ToList();


                return stores;
            }
        }

        public static Entities.Shop.Shop Shop(int ShopId)
        {
            using (var session = NHibernateHelper.OpenSession()) //bişey okurken transaction gerekmez.
            {
                return session.CreateCriteria(typeof(Entities.Shop.Shop))
                    .Add(Restrictions.Eq("ShopId", ShopId))
                    .SetMaxResults(1)
                    .UniqueResult<Entities.Shop.Shop>();
            }
        }
    }
}

Fluent NHibernate Mapping Example

namespace DAL.Shop
{
    public class ShopMap : ClassMap<Entities.Shop.Shop>
    {
        public ShopMap()
        {
            Id(x => x.ShopId);

            Map(x => x.ShopName);
            Map(x => x.Status);
            Map(x => x.Activity);
            Map(x => x.Available);

            References(x => x.Address);

            HasMany(x => x.ShopScores);
            HasMany(x => x.ShopPromotions);
            HasMany(x => x.DeliveryDistricts);
            HasMany(x => x.PaymentMethods);
            HasMany(x => x.Menus);
            HasMany(x => x.WorkHours);
        }
    }

    public class ShopScoreMap : ClassMap<Entities.Shop.ShopScore>
    {
        public ShopScoreMap()
        {
            Id(x => x.ShopScoreId);

            Map(x => x.ShopScoreTypeId);
            Map(x => x.Score);
        }
    }

    public class ShopScoreTypeMap : ClassMap<Entities.Shop.ShopScoreType>
    {
        public ShopScoreTypeMap()
        {
            Id(x => x.ShopScoreTypeId);

            Map(x => x.ShopScoreTypeName);
        }
    }

    public class ShopPromotionMap : ClassMap<Entities.Shop.ShopPromotion>
    {
        public ShopPromotionMap()
        {
            Id(x => x.ShopPromotionId);

            Map(x => x.ShopPromotionTypeId);
        }
    }

    public class ShopPromotionTypeMap : ClassMap<Entities.Shop.ShopPromotionType>
    {
        public ShopPromotionTypeMap()
        {
            Id(x => x.ShopScoreTypeId);

            Map(x => x.ShopScoreTypeName);
        }
    }

    public class DeliveryDistrictMap : ClassMap<Entities.Shop.DeliveryDistrict>
    {
        public DeliveryDistrictMap()
        {
            Id(x => x.DeliveryDistrictId);

            References(x => x.District);
            Map(x => x.MinimumPaymentAmount);
        }
    }

    public class WorkHourMap : ClassMap<Entities.Shop.WorkHour>
    {
        public WorkHourMap()
        {
            Id(x => x.WorkHourId);

            Map(x => x.Day);
            Map(x => x.OpenAt);
            Map(x => x.CloseAt);
        }
    }
}

Unit Testing Example

namespace Test.Shop
{
    [SetUpFixture]
    public class SetUpClass
    {
        [SetUp]
        public void RunBeforeAnyTests()
        {
            Entities.Shop.Shop Shop = null;
            for (int i = 0; i < 1000; i++)
            {
                Shop = new Entities.Shop.Shop { ShopName = "Mc Donalds" };
                BL.Shop.CREATE.CreateShop(Shop);
            }
        }

        [TearDown]
        public void RunAfterAnyTests()
        {
            // ...
        }
    }

    [TestFixture]
    public class READ
    {
        [Test]
        public static void All()
        {
            IList<Entities.Shop.Shop> Shops = BL.Shop.READ.All();

            Assert.AreEqual(1000, Shops.Count);
        }
    }
}
\$\endgroup\$
5
\$\begingroup\$

Browsing over the code one issue which jumped at me is the fact you have a tight coupling between your business layer and data access layer. Your BL is calling straight into the DAL by calling DAL.Entity.CRUD.Whatever(). This means that if you want to unit test your BL all of a sudden you have to set up a repository (most likely a database) while you should not have to. Testing the BL should not require to set up any other layer.

One way to achieve that is by injecting an interface to the DAL into the BL and all your test for BL.Shop.READ.All() then cares about is the appropriate method on the injected DAL interface was called. Then use a mocking framework like RhinoMocks or Moq to mock the DAL interface.

\$\endgroup\$
  • \$\begingroup\$ this is exactly what type answers I am looking for! thank you, I will check mocking asap. apart from that everything else looks cool? \$\endgroup\$ – Mert Mar 10 '14 at 11:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.