Blog Home  Home Feed your aggregator (RSS 2.0)  
kevin Mocha - Monday, February 01, 2010
Bookmarks collected from web.
 
 Monday, February 01, 2010
 Wednesday, January 27, 2010

Setting the value will force future processes in that space to use the specified .NET runtime, like:

set COMPLUS_Version = v3.5

That would force everything to run in .NET 3.5.

http://www.cookcomputing.com/blog/archives/000597.html

It is not necessary to rebuild NUnit. I discovered that if you add the following to the relevant NUnit application config file you can run a test dll built for .NET 4.0. Under <configuration> add:

<startup>
  <requiredRuntime version="v4.0.20506" />
</startup>

and under <runtime> add:

<loadFromRemoteSources enabled="true" />
Wednesday, January 27, 2010 3:49:24 PM UTC  #    Comments [0]    |   |  Trackback
 Monday, January 25, 2010

(By Eric Evan)

Chapter 1 What Is Domain-Driven Design

When we begin a software project, we should focus on the domain it is operating in. The entire purpose of the software is to enhance a specific domain.

How can we make the software fit harmoniously with the domain? The best way to do it is to make software a reflection of the domain.

The model is our internal representation of the target domain, and it is very necessary throughout the design and the development process.

There are different approaches to software design. One is the waterfall design method. This method involves a number of stages. The business experts put up a set of requirements which are communicated to the business analysts. The analysts create a model based on those requirements, and pass the results to the developers, who start coding based on what they have received. It’s a one way flow of knowledge. While this has been a traditional approach in software design, and has been used with a certain level of success over the years, it has its flaws and limits. The main problem is that there is no feedback from the analysts to the business experts or from the developers to the analysts. Another approach is the Agile methodologies, such as Extreme Programming (XP). These methodologies are a collective movement against the waterfall approach, resulting from the difficulties of trying to come up with all the requirements upfront, particularly in light of requirements change. It’s really hard to create a complete model which covers all aspects of a domain upfront. It takes a lot of thinking, and often you just cannot see all the issues involved from the beginning, nor can you foresee some of the negative side effects or mistakes of your design. Another problem Agile attempts to solve is the so called “analysis paralysis”, with team members so afraid of making any design decisions that they make no progress at all. While Agile advocates recognize the importance of design decision, they resist upfront design. Instead they employ a great deal of implementation flexibility, and through iterative development with continuous business stakeholder participation and a lot of refactoring, the development team gets to learn more about the customer domain and can better produce software that meets the customers needs.

 

The Agile methods have their own problems and limitations; they advocate simplicity, but everybody has their own view of what that means. Also, continuous refactoring done by developers without solid design principles will produce code that is hard to understand or change. And while the waterfall approach may lead to over-engineering, the fear of overengineering may lead to another fear: the fear of doing a deep, thoroughly thought out design.

 

Chapter 2 The Ubiquitous Language

A core principle of domain-driven design is to use a language based on the model. Since the model is the common ground, the place where the software meets the domain, it is appropriate to use it as the building ground for this language.

Building a language like that has a clear outcome: the model and the language are strongly interconnected with one another. A change in the language should become a change to the model.

 

 

Chapter 3 Model-Driven Design

A better approach is to closely relate domain modeling and design. The model should be constructed with an eye open to the software and design considerations. Developers should be included in the modeling process.

 

image

 

image

 

 

image

 

Entities: There is a category of objects which seem to have an identity, which remains the same throughout the states of the software. For these objects it is not the attributes which matter, but a thread of continuity and identity, which spans the life of a system and can extend beyond it. Such objects are called Entities.

 

Value Objects:  There are cases when we need to contain some attributes of a domain element. We are not interested in which object it is, but what attributes it has. An object that is used to describe certain aspects of a domain, and which does not have identity, is named Value Object.

It is highly recommended that value objects be immutable.
One golden rule is: if Value Objects are shareable, they should be immutable. Value Objects should be kept thin and simple. When a Value Object is needed by another party, it can be simply passed by value, or a copy of it can be created and given.

 

Services:

we discover that some aspects of the domain are not easily mapped to objects.  But there are some actions in the domain, some verbs, which do not seem to belong to any object. They represent an important behavior of the domain, so they cannot be neglected or simply incorporated into some of the Entities or Value Objects. When such a behavior is recognized in the domain, the best practice is to declare it as a Service. Such an object does not have an internal state, and its purpose is to simply provide functionality for the domain. The assistance provided by a Service can be a significant one, and a Service can group related functionality which serves the Entities and the Value Objects.

(For example, to transfer money from one account to another; should that function be in the sending account or the receiving account? It feels just as misplaced in either.)

There are three characteristics of a Service:
1. The operation performed by the Service refers to a domain concept which does not naturally belong to an Entity or Value
Object.
2. The operation performed refers to other objects in the domain.
3. The operation is stateless.

 

Modules: it is necessary to organize the model into modules. Modules are used as a method of organizing related concepts and tasks in order to reduce complexity.

Another reason for using modules is related to code quality. It is widely accepted that software code should have a high level of cohesion and a low level of coupling.

Two of the most used are communicational cohesion and functional cohesion.

 

 

Three patterns:  Aggregate is a domain pattern used to define object ownership and boundaries. Factories and Repositories are two design patterns which help us deal with object creation and storage.

 

An Aggregate is a group of associated objects which are considered as one unit with regard to data changes.

 

The root is an Entity, and it is the only object accessible from outside. The root can hold references to any of the aggregate objects, and the other objects can hold references to each other, but an outside object can hold references only to the root object.

Cluster the Entities and Value Objects into Aggregates and define boundaries around each. Choose one Entity to be the root of each Aggregate, and control all access to the objects inside the boundary through the root. Allow external objects to hold references to the root only. Transient references to internal members can be passed out for use within a single operation only.

 

Factories are used to encapsulate the knowledge necessary for object creation, and they are especially useful to create Aggregates. When the root of the Aggregate is created, all the objects contained by the Aggregate are created along with it, and all the invariants are enforced.
A Factory Method is an object method which contains and hides knowledge necessary to create another object.

 

There are times when a Factory is not needed, and a simple constructor is enough. Use a constructor when:
• The construction is not complicated.
• The creation of an object does not involve the creation of others, and all the attributes needed are passed via the constructor.
• The client is interested in the implementation, perhaps wants to choose the Strategy used.
• The class is the type. There is no hierarchy involved, so no need to choose between a list of concrete implementations.

 

 

 

Therefore, use a Repository, the purpose of which is to encapsulate all the logic needed to obtain object references.

The overall effect is that the domain model is decoupled from the need of storing objects or their references, and accessing the
underlying persistence infrastructure. Provide repositories only for Aggregate roots that actually need direct access. Keep the client focused on the model, delegating all object storage and access to the Repositories.

 

There is a relationship between Factory and Repository. They are both patterns of the model-driven design, and they both help us to manage the life cycle of domain objects. While the Factory is concerned with the creation of objects, the Repository takes care of already existing objects.

 

Chapter 4 Refactoring Toward Deeper Insight

 

One of the first things we are taught about modeling is to read the business specifications and look for nouns and verbs. The nouns are converted to classes, while the verbs become methods. This is a simplification, and will lead to a shallow model.

We start with a coarse, shallow model. Then we refine it and the design based on deeper knowledge about the domain, on a better understanding of the concerns. We add new concepts and abstractions to it. The design is then refactored. Each refinement adds more clarity to the design. This creates in turn the premises for a Breakthrough.

 

To reach a Breakthrough, we need to make the implicit concepts explicit.

The first way to discover implicit concepts is to listen to the language.

Try to see if there is a missing concept.

 

Another obvious way of digging out model concepts is to use domain literature.

 

There are other concepts which are very useful when made explicit: Constraint, Process and Specification.

Placing the Constraint into a separate method has the advantage of making it explicit.
Processes are usually expressed in code with procedures.
Simply said, a Specification is used to test an object to see if it satisfies a certain criteria. The domain layer contains business rules which are applied to Entities and Value Objects. Those rules are usually incorporated into the objects they apply to. When rule is not a simple method and spans many entities and value objects,  the rule should be encapsulated into an object of its own, which becomes the Specification of the Customer, and should be kept in the domain layer.

 

 

Chapter 5 Preserving Model Integrity

 

This chapter is about large projects which require the combined efforts of multiple teams.

 

Instead of trying to keep one big model that will fall apart later, we should consciously divide it into several models.

Each model should have a clearly delimited border, and the relationships between models should be defined with precision.

 

image

 

A model should be small enough to be assigned to one team.

 

Bounded Context: The main idea is to define the scope of a model, to draw up the boundaries of its context, then do the most possible to keep the model unified.
Explicitly set boundaries in terms of team organization, usage within specific parts of the application, and physical manifestations such as code bases and database schemas. Keep the model strictly consistent within these bounds, but don’t be distracted or confused by issues outside.

A Bounded Context is not a Module. A Bounded Context provides the logical frame inside of which the model evolves. Modules are used to organize the elements of a model, so Bounded Context encompasses the Module.

 

A Context Map is a document which outlines the different Bounded Contexts and the relationships between them. What it is important is that everyone working on the project shares and understands it.

 

A common practice is to define the contexts, then create modules for each context, and use a naming convention to indicate the context each module belongs to.

 

The purpose of the Shared Kernel is to reduce duplication, but still keep two separate contexts.

 

Core Domain and Generic Subdomain

 

Last Chapter

 

Keep in mind some of the pitfalls of domain modeling:
1) Stay hands-on. Modelers need to code.
2) Focus on concrete scenarios. Abstract thinking has to be anchored in concrete cases.
3) Don't try to apply DDD to everything. Draw a context map and decide on where you will make a push for DDD and where you will not. And then don't worry about it outside those boundaries.
4) Experiment a lot and expect to make lots of mistakes. Modeling is a creative process.

Monday, January 25, 2010 9:54:21 PM UTC  #    Comments [0]    |   |  Trackback
 Friday, January 15, 2010

http://referencesource.microsoft.com/serversetup.aspx

Configuring Visual Studio for Debugging

Set Up Visual Studio 2008:

a. Install and set up Visual Studio 2008 including any updates.

Set Up the Symbols Path:

a. Launch Visual Studio 2008.
b. From the Tools menu, choose Options.
c. In the Options dialog box, open the Debugging node and select General
        a. Clear 'Enable Just My Code (Managed only)'
        b. Check 'Enable source server support'

d. Select Symbols under Debugging.
e. In the Symbol File Locations box, add the following location:
   http://referencesource.microsoft.com/symbols

   Note: To add the Symbols path Click folder icon.
f. Enter in text box under 'Cache symbols from symbol servers to this directory:' C:\Symbols\RSCC:
   Note : If C:\Symbols is already in use then you can chose another folder name. The folder name must be input into the
   text box
g. Click OK.

Debugging your Application

a. Open your application code solution and build the solution.
b. Set a break point in the code.
c. Start debugging (press F5).
d. EULA pops up, click Accept.
e. Source code will be downloaded.

Friday, January 15, 2010 9:14:56 PM UTC  #    Comments [0]    |  Trackback
 Thursday, January 14, 2010

Model-View Architecture

image

Three-Tie Architecture

image

Model-View-Controller Architecture

image

image

image

 

The preceding test is a unit test, because it tests just one isolated component: AdminController.
It doesn’t rely on any real implementation of IMembersRepository, and so it doesn’t need to
access any database.

 

When you deliberately chain together a series of components and test them together,
that’s an integration test.

 

image 

image

image

image

image

Thursday, January 14, 2010 10:35:20 PM UTC  #    Comments [0]    |  Trackback
 Thursday, December 03, 2009
 Wednesday, December 02, 2009
Wednesday, December 02, 2009 2:59:17 PM UTC  #    Comments [0]    |  Trackback
 Monday, November 09, 2009
Monday, November 09, 2009 11:22:48 PM UTC  #    Comments [0]    |  Trackback

Understand how event increase the runtime coupling among objects.

Event-based communication loosens the static coupling between types, but it comes at the cost of tighter runtime coupling between the event generator and the event subscribers. The multicast nature of events means that all subscribers must agree on a protocol for responding to the event source. The event model, in which the event source holds a reference to all subscribers, means that all subscribers must either (1) remove event handlers when the subscriber wants to be disposed of or (2) simply cease to exist. Also, the event source must unhook all event handlers when the source should cease to exist. You must factor those issues into your design decision to use events.

public class DoesWorkThatMightFail
{
    public bool TryDoWork()
    {
        if (!TestConditions())
            return false;
        Work(); // may throw on failures, but unlikely
        return true;
    }

    public void DoWork()
    {
        Work(); // will throw on failures.
    }

    private bool TestConditions()
    {
        // body elided
        // Test conditions here
        return true;
    }

    private void Work()
    {
        // elided
        // Do the work here
    }
}

 

 

 

You should expand your set of design choices and use both composition and inheritance. When you create types that reuse implementation from other types, you should use composition. If your types model an Is A relationship in every way, inheritance is the better choice. Composition requires more work to expose the implementation from the inner objects, but the payoff is more control over the coupling between your type and the type whose implementation you wish to reuse. Using inheritance means that your derived type is a special case of the base class in every way.

Extension methods provide a mechanism for C# developers to define behavior in interfaces. You can define an interface with minimal capabilities and then create a set of extension methods defined on that interface to extend its capabilities. In particular, you can add behavior instead of just defining an API.

 

In short, it's best to declare local variables using var unless developers (including you, in the future) need to see the declared type to understand the code. The title of this item says "prefer," not "always." I recommend explicitly declaring all numeric types (int, float, double, and others) rather than use a var declaration. In addition, use the type parameter in generics (for example T, tresult) rather than var. For everything else, just use var. Merely typing more keystrokes—to explicitly declare the type—doesn't promote type safety or improve readability. You may also introduce inefficiencies that the compiler will avoid if you pick the wrong declared type.

 

Anonymous types aren't as exotic as they seem, and they don't harm readability when they are used correctly. If you have interim results that you need to keep track of and if they're modeled well with an immutable type, then you should use anonymous types. When you need to define behaviors on those types, that's when you need to create concrete types to represent those concepts. In the meantime, the compiler can generate all the boilerplate code you need. You clearly communicate to other developers that the type is used only within the context of that method and those generic methods it calls.

Monday, November 09, 2009 9:13:48 PM UTC  #    Comments [0]    |  Trackback
Copyright © 2010 Kevin Mocha. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.
Pick a theme: