September 2006 - Posts
The ADO.NET vNext team decided to release the Entity Data Model (EDM) Designer Prototype. I tried the early bits on a demo I prepared for an internal event next week and later this year at the (Dutch) Software Developer Event, 11th December 2006, Ede. It will be very interesting to see, assuming the designer is based on the current Domain Specific Language tools bits, what functionality will be embedded eventually and what effect this new technology has on the usability experience.
You can download the Entity Data Model (EDM) Designer Prototype here.
Why do I spend so much time with the ADO.NET vNext bits? Udi just reminded me why with his post Web Service Software Factory – Data Access CRUD! Web Service Software Factory implements (or at least the generated code base does) the Three-Layered Services Application reference architecture in which data and behavior are scattered throughout the software (see Organizing Domain Logic for an in-depth discussion). I can only hope better tooling produced by the source itself will help .NET developers realize there is an (better) alternative to layer a service-oriented application.
With no adequate tooling in place to support a particular design pattern it wouldn't make sense to promote it.
First I was, now I won't be able to make it to Barcelona. What a waste!
When I earlier said that ADO.NET vNext will not be included in .NET Framework 3.0
and questioned the reasoning behind .NET Framework versioning
, now Brad Abrams
mentions a possible .NET Framework 3.5
including support for LINQ and "it", assuming Pablo Castro refers to "it" being the ADO.NET vNext bits. Interesting developments!
Also see the first, second, third and fourth part of this series of posts on the next generation data access for the .NET platform.
Entity SQL currently does not include support for the Data Manipulation Language (update, delete, insert into functions) and according to Daniel Simmons possibly not even for the first release of the Entity Framework (discussion). Updates to entities must be made through the object services layer by calling SaveChanges on an ObjectContext instance.
The team is currently actively working on support for stored-procedures (discussion).
CommandBehavior.SequentialAccess is here to stay (discussion). You'd want to use Query<T> anyway.
Table with self-references will be supported in future releases (discussion).
Abstract entities will be supported in future releases (discussion).
XML data type will be supported in future releases (discussion).
Frequently discussions on the Domain-Driven Design list contain some real gems. So does a topic started by Bil Simer topic "Loading business entities and bypassing business rules".
We have a business entity that has various rules. For example the length of
the title of a project (yeah yeah, data validation vs. real business rule
but walk with me on this). So for the title to be valid, it can't be null.
However the user says they want to be able to create stuff and come back to
it later so while there's a business rule on the validation, the business
object itself can be pretty empty (as long as we can recall it for the user
to modify later). So it's a bit of a quandary. A rule that says "the title
of the project must not exceed 50 characters and not be empty" but a user
who says "the system must allow me to save something to edit later in any
This is a situation where Domain-Driven Design really shines. A possible solution is to add a constraint to the database by setting the maxlength on the title field for the Product entity, and set the allowsnull property to false. Of course the class wrapping the Product entity has to make sure that the Title property is initialized with an empty string before persisting it. Remember when I said behavior is scattered across the layers in Organizing Domain Logic?
With a model focus we have the solution at hand. This however, does mean we should handle the database with care!
A Domain Object regardless of its state, should be savable
Some objects go through a one-way lifecycle, from an initial state to a final state, but most of the time the object's state is determined through their interactions. Lifecycle states are usually recorded in read-only properties that are changed during conduct business services. So in the case of Bil's example the Project is broken down into stages, since projects are rarely tackled as a single, monolithic job. A project progresses through the lifecycle states of planning, design, construction, commissioning, operation and termination. The planning state can have a derived lifecycle state concept, pre-feasibility etc.
Always is a "big" word because we should try to avoid reaching those states that make us jump through hoops in order to make them persistable. There are a couple of design principles to keep in mind. The first principle is knowing where in the lifecycle by making the lifecycle state a property on the object. The second principle says rules should be located with state which translates to the best practice that rules should be defined as closely as possible to the relevant lifecycle states.
I remember a posting talking about loading a domain object from a
persistence store where it would bypass the rules. I ran into the problem
today because I loaded up my domain object and started to map the values
from the data entity. The entity holding all the values from the database
were pretty empty, but when I wrote the mapping from service entity to
business object, my business logic failed (title cannot be null for
example). So I was stuck without being able to set the values (even if they
were empty) on my business object .
The problem of setting values in an instance that is being recreated by reading its values back from the database is a generic problem. There are several ways to deal with this problem:
Reconstitute a Domain Object from persistence
Through a specific constructor used just for reconstitution. It could look like this:
public Project(DataRow row)
public Project(int id, title description, ...)
Another option is through a specific method SetField(int fieldIndex, object value) and finally the least intrusive solution is through the use of reflection against private fields. For a great explanation and the pro's and con's of either solution see Jimmy Nilsson [Nilsson ADDDP].
Nilsson, Jimmy. Applying Domain-Driven Design and Patterns with Examples in C# and .NET. Addison-Wesley, 2006.
[Nicola et al. SOM]
Nicola, Jill, Mark Mayfield, and Mike Abney. Streamlined Object Modeling: Patterns, Rules, and Implementations. New Jersey: Prentice Hall, 2002.
The most popular post on this blog with over 50k views is Error while trying to run project: Unable to start debugging on the web server. Just recently I turned on comments again (since it has caught some spam over the years) and found a valuable suggestion from Michael:
gracias mucho - Microsoft doesn't seem to know this - or refusing to put it in their help document
Microsoft please update KB (306165) PRB: "Unable to start debugging on the Web server" error message when you debug ASP.NET applications with this information.
Also see the first, second and third part of this series of posts on the next generation data access for the .NET platform.
Currently there is no support in ADO.NET vNext for an entity base class. At least not a type that doesn't require to have a key as part of its definition [discussion]. A silly hack is to store the entity type in the Conceptual EDM and let all entities inherit from it [discussion].
Currently there is no support in ADO.NET vNext to re-generate the Mapping and Store Schema after you make a change to the database (also see ADO.NET Entity Framework Metadata). The team is thinking about the best way to make this possible in future releases [discussion].
Currently there is no support in ADO.NET vNext for Locking hints like NOLOCK [discussion]. According to Pablo Castro it's hard to come up with a general purpose mechanism to support locking hints without loosing the database independence. No specific plans.
Recent activity on the Domain-Driven Design user group made me decide to share this writing dating November 2005.
Almost a year ago someone asked me whether I have read Domain-Driven Development (DDD) and if so, what a typical service on top of a rich domain model could look like. After giving it some thought I failed to come up with a crystal clear answer. Discussing my ideas with Stefan Nijenhuis culminated in a confusion of tongues. This eventually led to the name of this article in which we both felt comfortable.
Let's see what others have to say about this topic:
Eric Evans: Some concepts from the domain aren’t natural to model as objects. Forcing the required domain functionality to be the responsibility of an Entity or Value either distorts the definition of a model-based object or adds meaningless artificial objects. When a significant process or transformation in the domain is not a natural responsibility of an Entity or ValueObject, add an operation to the model as a standalone interface declared as a Service. Define the interface in terms of the language of the model and make sure the operation name is part of the UbiquitousLanguage. Make the Service stateless. DDD Services
Martin Fowler: Enterprise applications typically require different kinds of interfaces to the data they store and the logic they implement: data loaders, user interfaces, integration gateways, and others. Despite their different purposes, these interfaces often need common interactions with the application to access and manipulate its data and invoke its business logic. The interactions may be complex, involving transactions across multiple resources and the coordination of several responses to an action. Encoding the logic of the interactions separately in each interface causes a lot of duplication. A Service Layer defines an application's boundary [Cockburn PloP] and its set of available operations from the perspective of interfacing client layers. It encapsulates the application's business logic, controlling transactions and coordinating responses in the implementation of its operations. PoEAA ServiceLayer
Microsoft: You are designing an enterprise application, and you need to make some of its functionality available across a network. This functionality needs to be accessible to various types of systems, so interoperability is a key aspect of the design. In addition to interoperability, you also may need to support different types of communications protocols and accommodate varying operational requirements. MPP ServiceInterface
Since there are so many different definitions for a service (see above), each discussion about what a service could look like seems to end in an endless loop. It is clear that we occasionally need 'a' service. In a recent project we defined a service class per use-case. A service class and its operations act as route signs to the consumers of the domain model. Mark den Hartog made the following comment:
Route signs point you in the right direction, they only take you as far as the "how to reach your end destination". A service should take you from point A to B without leaking the "how".
Although he does have a point, I still think that in terms of the domain model you need to know about the implementation details inside your service. Mark’s (being an integration specialist) comments drive towards MPP ServiceInterface and PoEAA ServiceLayer.
Another interesting metapor I have borrowed from Mark:
We find the Domain Model Service as an internal procedure within the city hall. The form is translated to specific domain objects and distributed to one or more persons handling the request. All persons have some knowledge of the procedures of the other persons, how much depends on the complexity of the tasks.
So, essentially the Domain Model Service is an integral part of the application and may therefore have knowledge of the internal structure of the domain, like business exception handling, object discovery etc. A Domain Model Service encapsulates behavior of the domain that does not fit in the domain objects themselves. Typical characteristics of a Domain Model Service is that it tends to be procedural and does not carry any state.
Also see Applying the Application Layer in Domain-Driven Design.
Also see the first part and second part of this series of posts on the next generation data access for the .NET platform.
Specify a property type to be of an Enumeration Type [discussion]. Lucky for us the team is currently looking into enumeration types and also feel that it would be nice to have them.
Relationship with payloads is a way to model table A, table B and table AB with a DateTime field indicating when the relationship was established [discussion]. Right now the Entity Framework doesn't have a way to avoid defining three entity types to model this relationship using two simple 1:1 mappings. This is something the team would like to support in future releases, because the need is apparent.
Autogenerated Fields is a must-have feature [discussion].
Unique Constraints and Range Values is something the team is looking at [discussion].
Entity Mapper is a tool the tools team is working on that helps to create and edit mapping using a graphical user interface [discussion]. It allows for testing the mappings and issuing canned and free-style Entity SQL questions against an EDM schema. What about a tool to support the LINQ to Entities layer?
It will be possible to generate the relational database schema from the EDM schema using the Entity Mapper tool [discussion]. I'm really looking forward to this feature since it allows for a more Domain Driven Design style in which you take the model-first approach. What a coincidence, since I discussed the importance for supporting the model-first approach in tooling the other day with my colleagues Olaf and Melchior.
More Posts Next page »