What is LINQ?
LINQ stands for Language Integrated Query and is a DSL within C# for querying data. It is implemented by language extensions to C# 3.0. It allows us to concisely express queries against our collections of data. LINQ comes in a variety of flavours: Objects, SQL, and XML which allow us to query different sources of data. LINQ is an internal DSL. The query expressions that we write are declarative statements about what we want, to project, restrict, etc. our data. The compiler maps them into imperative statements: method calls, lambda expressions, initializers etc.
LINQ gains the flexibility to target different collection types by allowing query expressions against both IEnumerable, for standardized collections, and IQueryable for others. IQueryable exploits the ability in C# 3.0 to treat code as data. A lambda expression can either be represented as a delegate or as an expression tree. Framework authors can provide implementations of IQueryProvider to interpret expression trees and emit code appropriate to the target. So LINQ to SQL takes expression trees and turns them into SQL statements.
But as well as providing implementations of IQueryable and IQueryProvider, LINQ also provide additional services for working with those collections. LINQ to SQL provides us with a Table<T> class that allows us to treat a table in an RDBMS as though it were an in-memory collection of objects of type T, supporting CRUD operations on elements in the collection. The associated DataContext allows us to control the persistence of elements within that collection. It is important to recognize this as when we talk about LINQ we often need to be clear if we are talking about a DSL for querying collections of data or new framework classes for those collections of data. Some of the features under the LINQ brand are specific, whereas the DSL for queries is intended to be generic.
A layered architecture is one organizing principle for software, though not the only one.Think of the layers within software as looking something like a layer cake – each layer stands upon the foundations of the one below. We allow each layer to know about the services offered by the layer below it, but we do not allow the layer to know about the consumers of its services. A layer is independent of layers above it, but dependent on the layers below it. To manage our dependencies, our layer tends to depend on abstractions in the layer below, not concrete details. If we can, we narrow the surface area of our layer, to a small number of services that encapsulate what our clients know about. That allows us to change many of the details of our layer, as long as the published contract for how you interact with the layer remains constant. These points of connection are called facades.We use layers within software to:
- Manage complexity; we only care about what is in the layer.
- Provide alternative implementations; so that we can meet new requirements
- Allow re-usability at a coarse-grained level; each layer might have value to other consumers
A Layered architecture
There are a number of ways to layer our model. Here we divide it up into presentation, application services, domain, and infrastructure services.
The presentation layer is responsible for showing information to the user and allowing the user to send us commands.
The application service layer co-ordinates the response of the domain layer to a request from the presentation layer. Its responsibilities do not include business logic, instead it has organizational or workflow logic that initiates work within the domain. Its state reflects the progress of tasks not the state of the domain.
The domain layer is the heart of the application, where the information that the business cares about is held and manipulated and rules are applied.
The infrastructure layer provides services that allow the other layers to work such as persistence and communication. Both the domain layer and the application services layer may use the infrastructure layer.
One variation is to decide that the application services and infrastructure services do the same thing, insulate the domain from something that wants to communicate with it, or that it wants to communicate to. This, service layer, is a set of adapters, which our application uses to communicate with ports which are the API for anything external such as UI or DB. An adapter, specific to the port type, converts a request on the port into calls on the domain and translates requests from the domain into calls out of the port. So in an MVC web application, the controller is an adapter, which takes requests from a Web UI port, turns that request from HTML into calls into the domain, and then turns the response back into HTML to send to an outgoing port. Cockburn calls this a hexagonal architecture.
The common thread here is that the domain is isolated from other aspects of the application.
Next time we will talk about which layers LINQ to SQL fits into, what patterns it implements, and how best to work with it.