Kurser och utbildning av IT-proffs och systemutvecklare

i Sök

Cornerstones utvecklarblogg

Alla Taggar

All Tags » Design   (RSS)

  • Isn't it boring to write crosscutting concerns?

    To make sure we have clean code and make it easy for us to maintain, we should try to be lazy and reuse code as much as possible, we should also avoid redundant code. But when it comes to crosscutting concerns, we have to be redundant, or? What code is mostly redundant in our code? I will assume that code to check security and logging exceptions are the most redundant code we write. A method should only do one thing, but we can't skip crosscutting concerns, we need it. So basically several method will do more than one thing. Wouldn't it be much better if we only focus on the core concern and skip the crosscutting concerns when we write our code? How can we skip the crosscutting concerns but still has it? The answer is Aspect Oriented Programming (AOP). The PAG team has a Policy Injection Application BLock (PIAB) which we can use to intercept our crosscutting concerns into our code, we also have Spring.Net and some other frameworks. By using AOP frameworks we don't need to write the same code for logging exception etc over and over again, we will also have a much cleaner code, and our focus will only be the core concern. Oh, I feel so lazy, but why should I spend time to write code that do the same thing over and over again, it's so boring, isn't it :P Are you tired of writing crosscutting concerns over and over again, and do you use AOP today?
  • Returning IQueryable<T>

    Since LINQ was added to the .Net Community as a new wonderful new player, more and more solutions I have seen returns the IQueryable<T> from the Data Access Layer. One reason is to easy create different kind of queries in an easy way and execute them. Some developers use the IQueryable<T> interface to create a light weight interface for the Data Access Layer. It's an interesting solution, but at the moment I don't like it.

    If we look at how developers uses the IQueryable<T>, we often see code like this:

    public class CustomerRepository/CustomerDAL

    public IQueryable<Customer> GetCustomers()

    What is wrong with this code?

    1) The GetCustomers method is lying (A method is there to communicate). It will not get the Customers, it will return a Query object which can be used to create a Query for getting customers. A better name for the method would be GetQueryableCustomers or maybe GetQueryObjectForCustomers. If we want to use the name GetCustomers, I think the name of the Class which has this member would have the word Query in the name, for example: QueryProvider.GetCustomer. This will make sure the users of the code, know that we are getting a Query nothing else. So when return the IQueryable<T>, we are basically using a Query Provider, which should be used by the Data Access Layer, no other layers.

    2) By passing the IQueryable<T> between the layers, we will have a deferred execution. We will "never" know where and when the execution will take place (If we own the code, we will, but not is some other developers want to use our code). For me this is like passing SQL statements from the Data Access Layer up to the Business or Presentation layer for later execution.

    By not passing the IQueryable<T> from the Data Access Layer to the Business Logic Layer, we will know when the execution will take place, and when. If we use the Repository Pattern, all execution of Queries should take place inside of the Repository. It sad that the IQueryable<T> is indirect bound to a specific LINQ feature, such as Entity Framework or LINQ to SQL. What I want, is a way to attach a IQueryable<T> to a LINQ feature. In that way I could use it as a replacement of the Specification pattern/Query object pattern, and that would solve a lot of problem and also result in a light weight interface for the Data Access components.

    public IEnumerable<Customer> GetCustomersBySpecification(IQueryable<Customer> query)

    If this was possible and if we could use Entity Framework or LINQ to SQL as the infrastructure of our Repositories, we could create a Factory to return a IQueryable<T> interface which it not indirectly attached to a specific LINQ feature. In this case we could create our queries in the Business Logic layer, and pass the Query back down to the Data Access Layer and let it attache the Query to a LINQ feature and execute it:

    var query = from customer in QueryFactory.GetQuery<Customer>()
    where customer.ID = 1234 select customer;

    var customers = CustomerRepository.GetCustomerBySpecification(query);

    By using this solution we could avoid deferred execution, when and where the execution will take place is under our control.

    Before I end this post I want to let you know that the problem is not about returning the IQueryable<T> interface, the problem is how the LINQ features are indirect bound to the IQueryable<T> interface. If it wasn't and we could bind it later, I think we could use it to solve problems in a really wonderful and nice way. What do you think?

  • Map Objects to one Object

    In my previous post I wrote about how we could use Dynamic Compilation for mapping object to object in a configuration file. I spend a few minutes to see if I could do something more to it. It ended up that I can use it to several things, like creating Factories, or send in different kind of objects and map several into one. Here is how I for example can send in more domain object to map them into a PresentationCustomer:

    var presentationCustomer = map.Map<PresentationCustomer>(
                                        "CustomerToPresentationCustomer", 
                                        customer, 
                                        address);


    My configuration file look like this:

    public PresentationCustomer CustomerToPresentationCustomer(Customer customer, Address address)
    {
           return new PresentationCustomer()
                      {
                           ID = customer.ID,
                           CompanyName = customer.CompanyName,
                           FirstName = customer.FirstName,
                           LastName = customer.LastName,
                           Street = address.Street
                      };
    }


    Some comments I got was also to automatically map properties from object with the same name, so I added an extension method called MapTo, to make that possible, it will also open up support for mapping specific properties manually:

    public PresentationCustomer CustomerToPresentationCustomer(Customer customer, string lastName)
    {
          var presentationCustomer = new PresentationCustomer();
    
          customer.MapTo(presentationCustomer);
    
          presentationCustomer.FullName = customer.FirstName + " " + customer.LastName;
    
          return presentationCustomer;
    }


    I did also add support so other developers can simply add their own code which could be used by the configuration file. It's done by adding the namespace and an assembly of the code to the mapper.

    DynamicMapper map = new DynamicMapper();
    
    map.Assemblies.Add("MyHelper.dll");
    map.Namespaces.Add("MyHelper");
    
    var presentationCustomer = map.Map<PresentationCustomer>(
                                                   "CustomerToPresentationCustomer", 
                                                    customer, 
                                                    "Normén");


    Here is the MyHelper:


    namespace MyHelper
    {
        public static class MyExtension
        {
            public static string GetName(this string value)
            {
                return "Fredrik";
            }
        }
    }


    I can now use this extension method in my configuration file:


    public PresentationCustomer CustomerToPresentationCustomer(Customer customer, string Name)
    {
           return new PresentationCustomer()
                      {
                           ID = customer.ID,
                           CompanyName = customer.CompanyName,
                           FirstName = name.GetName(),
                           LastName = customer.LastName,
                           Street = address.Street
                      };
    }


    Because I can pass in several objects and map them to one single object, I can also pass in XmlDocument, DataSet, DataTable and SqlDataReaders etc and map them to an object:


    var presentationCustomer = map.Map<PresentationCustomer>(
                                        "CustomerToPresentationCustomer", 
                                        customer, 
                                        sqlReader);
    public PresentationCustomer CustomerToPresentationCustomer(Customer customer, SqlDataReader reader)
    {
           return new PresentationCustomer()
                      {
                           ID = customer.ID,
                           CompanyName = customer.CompanyName,
                           FirstName = customer.FirstName,
                           LastName = customer.LastName,
                           Street = reader["Street"]
                      };
    }


    I can think of using this solution if I don't use an ORM but still want to bind data from a SqlDataReader to an object, or combine several object and use formatting and specifying default values which could be changed over time, and when it does I don't need to recompile my code, only change the configuration file.


Den här bloggen

Syndication