Archive

Archive for the ‘C#’ Category

LINQ To SQL, Dynamic Querying & Fetching Strategies (cont)

July 15th, 2008 Simon Segal 4 comments

I posted recently on using the Specification Pattern and utilizing the generic Expression<> and Func<> to dynamically change the criteria of SQL queries generated by the LINQ To SQL implementation. I promised to come back with an approach on enabling Eager Loading by implementing a Fetching strategy, that can be used with my Repository. Here’s the Fetching Strategy code (most of it).

   1:  public interface IFetchingStrategy
   2:  {
   3:      DataLoadOptions LoadOptions { get; }
   4:  }
   5:   
   6:  public interface IFetchingStrategy<TRole> : IFetchingStrategy
   7:  {
   8:   
   9:  }
  10:   
  11:  public interface ICustomerLoyaltyDiscount
  12:  {
  13:   
  14:  }
  15:   
  16:  public class CustomerLoyaltyDiscountFetchingStrategy : 
  17:                   IFetchingStrategy<ICustomerLoyaltyDiscount>
  18:  {
  19:      private readonly DataLoadOptions _loadOptions;
  20:   
  21:      public DataLoadOptions LoadOptions
  22:      {
  23:          get { return _loadOptions; }
  24:      }
  25:   
  26:      public CustomerLoyaltyDiscountFetchingStrategy()
  27:      {
  28:          _loadOptions = new DataLoadOptions();
  29:          _loadOptions.LoadWith<Customer>(c => c.Orders);
  30:          _loadOptions.LoadWith<Order>(o => o.OrderLines);
  31:      }
  32:  }

Most of the code above is self explanatory except perhaps for the interface ICustomerLoyaltyDiscount on line 11. This interface is used to describe a role in my repository so I can dynamically lookup Fetching Strategies that take that role as a generic parameter and use them to fetch data.

   1:  internal static void SimpleRepositoryDynamicFetching()
   2:  {
   3:      Specification<poco.Customer> simonsCoSpec =
   4:          new Specification<poco.Customer>
   5:              (c => c.Country == "Germany");
   6:   
   7:      DataContext ctx = GetContext();
   8:   
   9:      Repository<poco.Customer> customerRepository =
  10:          new Repository<poco.Customer>(ctx);
  11:   
  12:      var custs = customerRepository.
  13:               All<ext.ICustomerLoyaltyDiscount>(simonsCoSpec);
  14:   
  15:      foreach (var cust in custs)
  16:      {
  17:          Console.WriteLine("The Name of the Customer " +
  18:                   "from Germany is {0}",
  19:                   cust.CompanyName);
  20:          foreach (var order in cust.Orders)
  21:          {
  22:              Console.WriteLine("\tOrder Number {0}", 
  23:                               order.OrderID);
  24:              foreach (var orderLine in order.OrderLines)
  25:              {
  26:                  Console.WriteLine("\t\tProduct ID {0} " +
  27:                      "Amount {1}",
  28:                      orderLine.ProductID, 
  29:                      (orderLine.Quantity * 
  30:                        orderLine.UnitPrice));
  31:              }
  32:          }
  33:      }
  34:  }

As you can see from the code above, when I call the Repository ALL method (as shown below), I use the overload that takes a generic parameter, indicating to the repository to look for a Fetching Strategy that also has this generic argument defined as its role.

   1:  public IList<T> All<TRole>(ISpecification<T> spec)
   2:  {
   3:      using (_context)
   4:      {
   5:          ext.IFetchingStrategy<TRole> strategy = 
   6:              DynamicFetchingStrategyLoad<TRole>();
   7:          _context.LoadOptions = strategy.LoadOptions;
   8:          return GetTable().Where(spec.EvalPredicate).
   9:                            ToList<T>();
  10:      }
  11:  }

The next time I post on this subject I will include the entire code, repository, specifications and fetching strategies.

Share/Save/Bookmark

Every Class a Class - Not JABOWS.

July 10th, 2008 Simon Segal 4 comments

A while back, thumbs_down Windows Communication Foundation (WCF) uber master Juval Lowy, was doing the rounds and proclaiming that every class we DotNet developers wrote could and should be WCF Services. This was all part of the assertion that WCF is as big as .NET itself and in some respects the next .Net. A very interesting idea but nothing I am about to start doing and certainly something I have yet to see embraced. Jimmy Nilsson wrote of a ‘default architecture’, in reference to the use of DDD, but defaulting to a position of ‘every class a WCF class’, just feels wrong.

Udi pointed out a while back that this approach gave cause for concern with regards to performance. If I make every class a WCF Service I am going to end up with heaps of potentially redundant configuration code and or files and significantly pollute my objects with WCF attributes and for me that does not effectively express my intent. Are we meant to make our domain model classes services too? Surely not.

As far as WCF goes for messaging, it does provide an excellent way to move my message over various transports quite simply and uniformly, however it still encourages an RPC way of working and most development I see with WCF does in fact employ that approach. Now I haven’t seen Juval’s training session or presentation on this idea but it seems to me that if every class is a WCF service then I’m pretty likely to end up with JABOWS and frankly pilling up the the Web Services in my architecture is definitely not something I want to do.

Juval was recently in Sydney training and I couldn’t help but wonder if he is promoting this idea as part of his WCF master class now?

Share/Save/Bookmark

Categories: C#, Distributed, SOA, Services, WCF Tags: , , , ,

LINQ to SQL, the Specification Pattern and Dynamic Queries

July 2nd, 2008 Simon Segal 1 comment

A while back Udi posted on Fetching Strategies that he implemented with NHibernate. I have just finished working on an implementation of the Specification Pattern that will work with LINQ (to objects) using Lambdas to provide the test logic and in the case of LINQ to SQL using the same testing predicates as search predicates when querying the database.

   1:  public static void SpecForLambdaWithDatabase()
   2:  {
   3:      Specification<Customer> coNameSpec =
   4:          new Specification<Customer>
   5:              (c => c.CompanyName == “Blauer See Delikatessen”);
   6:  
   7:      NorthwindDataContext ctx = new NorthwindDataContext();
   8:  
   9:      //TODO: Turn this into a fetching strategy that
  10:      //can be loaded when a Repository method is called
  11:      //using a role. Dependancy Injection will be useful 
  12:      //in allowing us slot in different fetching strategies 
  13:      //over time if required.
  14:      DataLoadOptions options = new DataLoadOptions();
  15:      options.LoadWith<Customer>(c => c.Orders);
  16:      options.LoadWith<Order>(o => o.OrderLines);
  17:      ctx.LoadOptions = options;
  18:  
  19:      //Note: the specification passes it’s EvalPredicate
  20:      //as a Func<T,bool> argument to the ‘Where’
  21:      //extension method
  22:      var exp = from c in ctx.Customers
  23:                .Where<Customer>(coNameSpec.EvalPredicate)
  24:                select c;
  25:  
  26:      foreach(var c in exp)
  27:      {
  28:          Console.WriteLine(“The Customer ID ‘{0}’ “ +
  29:              “AND NAME ‘{1}’”,
  30:              c.CustomerID, c.CompanyName);
  31:      }
  32:  }

My next goal is to enable the eager and lazy loading in these scenarios dealt with by using something similar to Fetching Strategies and have the Repository load them using dependency injection which will enable me to plug in the correct fetching strategy at will.

Shortly I will post some code that demonstrates all this with a Repository and not the standard .DBML file, DataContext way of doing things as per above.

Share/Save/Bookmark

Categories: C#, DDD, LINQ, LINQ To SQL, ORM Tags: , , , ,
Creative Commons Attribution-ShareAlike 2.5 Australia
Creative Commons Attribution-ShareAlike 2.5 Australia