software services

Windows 8 Developer Preview

Dashboard

Dash

Windows Explorer

The new Windows Explorer uses the Office 2010 Ribbon

Explorer8

Internet Explorer 10

Internet Explorer 10 offers a new ‘chrome-less’ mode.

Icons on the bottom bar are called ‘Charms’

IE10

Get Developing with Windows 8 and WinRT

Windows recently published Windows 8 Tech preview with Blend and a new build of Visual Studio that works with the WinRT.

Get Windows 8 and the Dev Tools

Links to tools you will need to get started:

Windows Developer Preview with developer tools English, 64-bit (x64) – DOWNLOAD (4.8 GB)

Windows Developer Preview English, 64-bit (x64) – DOWNLOAD (3.6 GB)

Windows Developer Preview English, 32-bit (x86) – DOWNLOAD (2.8 GB)

Microsoft Expression Blend Preview for Silverlight 5 – DOWNLOAD (93.0 MB)

 

The WinRT Architecture

clip_image0014

Know your Seam Events

Working with Seam and it’s event model can make things really easy through decoupling your observers from the actual framework.

Warning: If you don’t get to know the existing Seam event model, you will be subject to wasted code-time, use-less subtypes with overrides hacking in your functionality.

…Don’t punish yourself, please.


Context life-cycle

Converstation and postCreate

org.jboss.seam.preDestroyContext.<Context Name>
org.jboss.seam.postCreate.<Context Name>
org.jboss.seam.endConversation
org.jboss.seam.beginConversation
org.jboss.seam.conversationDestroyed
org.jboss.seam.conversationTimeout
org.jboss.seam.noConversation

Business Process

org.jboss.seam.createProcess.<Business Process Name>
org.jboss.seam.initProcess.<Business Process Name>
org.jboss.seam.endProcess.<Business Process Name>
org.jboss.seam.startTask.<Task Name>
org.jboss.seam.endTask.<Task Name>

Phase Events

org.jboss.seam.afterPhase
org.jboss.seam.beforePhase
note: your observer should take argument PhaseEvent. Just filter by known Phase Event Id.

Security

org.jboss.seam.security.initCredentials
org.jboss.seam.security.credentialsUpdated
org.jboss.seam.security.loginSuccessful
org.jboss.seam.security.loginFailed
org.jboss.seam.security.notLoggedIn
org.jboss.seam.security.notAuthorized
org.jboss.seam.security.preAuthenticate
org.jboss.seam.security.postAuthenticate
org.jboss.seam.security.loggedOut
org.jboss.seam.security.alreadyLoggedIn
org.jboss.seam.security.quietLogin
org.jboss.seam.notLoggedIn

Validation

org.jboss.seam.validationFailed
org.jboss.seam.transaction.transactionFailed

Locale and Timezones

org.jboss.seam.localeSelected.
org.jboss.seam.timeZoneSelected.

Obviously, you probably have what you need to hook into the correct life-cycle ‘moments’, so don’t reinvent the wheel and clutter up your design patterns.

Getting Started with JBoss and Seam

Seam Background

jboss-seam

Seam is useful for Aspect-Oriented Programming.

Its real muscle is a Dependency Management framework that allows Object Instance Injection/Outjection, which speeds up application development by a large factor.

It is also riding on top of a kick-butt web platform that almost all of the best open-source Web Tools (like Hibernate, iText, Drools, etc) can be configured into.

For Test-Driven-Developers, there is even a ‘head-less’ test class that can be used for mocking Java Server Faces requests against the Context Management framework. This allows for almost all of the application to be written before even selected an Application Server.

Most importantly, Seam has become popular with a new Major Release on the horizon.

 

Getting the Tools

Note: this tutorial is built using Mac OSX 32bit.

Download the JBoss-Seam Project, which is the Seam Framework + Project Generation scripts

Download the JBoss Application Server (AS)

Download Eclipse Helios 

 

Create the default Seam Project

Extract your JBoss Application Server at a noted location.

After extracting your JBoss-Seam project, navigate into the root and execute

chmod 755 seam

Next, run the following to start configuring the JBoss-Seam Project to build your project root:

./seam setup

This will run a script with a long series of questions which will configure your project options.

I highly recommend that you stick with the defaults by pressing enter, with exception to the Questions mentioned below:

Question Explanation
Enter the directory where you want the project to be created This is the actual root of the directory, not the [dir]/[project name], of your new project
Enter your JBoss AS home directory The JBoss Application Server Directory you have already extracted prior to this stage in the tutorial
Enter the project name Your desired Project Name
Enter the base package name for your Java classes In java, it is customary to create a ‘namespace’ that is branded for your company.

The namespace has three parts, [com].[company name].[project name]

For instance, if my company was named “Ted’s Shoes Inc.” I would brand my packages as com.tedshoes.shoewebsite

Do you want to recreate the database tables and execute import.sql each time you deploy This is very helpful when using modern Object Relational Mapping libraries for flushing the DB.

This tool is only designed for development, and should be turned off before Production deployment.

 

Once all of the questions are answered for the setup, you will get a “Build Success” console output.

Then, actually create the project by executing:

./seam create-project

It’s that simple.

 

Validate the project

Navigate into the new Project Directory.

Execute the following Build task:

ant explode

This task will Compile the default sources, package the web project, and then explode the web project into the JBoss Application server.

A successful installation will result in a “Build Successful” output.

 

Common Problems

Problem: “The JAVA_HOME environment variable is not set”

Resolution: http://www.mehtanirav.com/2008/09/02/setting-java_home-on-mac-os-x-105

 

Conclusion

The Seam Community has made it very easy to build your first project and get development immediately.

Now, with the knowledge of how to build a default project, you can begin to investigate the features of the Seam Container.

Code-first with the EntityFramework and ASP.NET MVC 2


For TDD (Test Driven Development) Life-Cycles, it is traditionally valuable to Unit Test Data Access Layers against a Mock Data Store.

This usually introduces interesting challenges related to Schema synchronization between a production DB and a local test Store; Especially when the Test Process requires heavy initialization, seeding, and potentially context-isolation across multiple threads.

This approach also implies more levels of abstraction and complicated dependency injection patterns to swap out implementations while still holding the integrity of test cases.

On the java stack, Hibernate offers domain driven design against a range of data stores making this problem a non-issue. The largest advantage being: Hibernate has the ability to build the DB Schema based on the Domain Model at runtime, without XML mapping clutter.

This is a tutorial on what the MS Stack has to offer in competition to this advantage.

Get the Tools

It should be mentioned up front, this methodology of ORM (Object Relational Mapping) is not consider production-mode yet.

 

Get the Entity Framework CTP

Download and Install Preview 4.

This will install the extension of the .NET 4.0 Entity Framework at

[drive]:\Program Files\Microsoft ADO.NET Entity Framework Feature CTP4\Binaries\

Install SQLCE 4

Download and install Microsoft SQL Server Compact 4.0 Community Technology Preview for Windows Desktop 

 

Creating the Project

First, we want to create an ASP.NET MVC 2 web application with Test project.

 

image

image

For anyone that hasn’t seen a default ASP.NET MVC 2 application before, essentially we get a MSTest class library already configured with default test cases against the templated Controllers.

image

Next, Add the Entity Framework CTP Binary dependency to the CodeFirstMVC project

image

Running CodeFirstMVC at this point would show the default web content

image

 

Building a Real-World Domain Model

One of the common paths for evolved SAS (Software-As-A-Service) Products is offering a subset of application functionality via a Membership Driven API (REST, SOAP, etc).

For most Hobbyists’, traditional ASP.NET Membership security checks on Requests would be acceptable when dealing with Role Isolation. But, this becomes much more complicated when working with other companies through existing protocols (SAML, Federated Grids, etc)

Since we want to design the SAS Product to be flexible towards these expected use-cases, it would be appropriate to create a Domain Driven Membership Model which can be integrated into each usage scenario as needed.

The user classes:

image

 

We start with the AbstractEntity which uses the [Key] and [Required] Annotations. These are the Runtime Hooks into the Domain Model that the Entity Framework uses to build our queries.

Note: It is very common to use a code issued GUID as a reliable identifier on Domain Objects across data stores. The Id Property, in this example, can really be thought of as a Primary Key on an underlying Table

namespace CodeFirstMVC.Models
{
    /// <summary>
    /// Represents an Abstract Domain Entity
    /// </summary>
    public abstract class AbstractEntity
    {
        public AbstractEntity()
        {
            this.Guid = Guid.NewGuid();
        }
        [Key]
        public int Id { get; set; }
        [Required]
        public Guid Guid { get; set; }
    }
}

 

Next, we need an Abstract User with common membership methods

namespace CodeFirstMVC.Models
{
    public class AbstractUser : AbstractEntity
    {
        public String Email { get; set; }
        public String UserName { get; set; }
    }
}

 

Then, the two concrete User type implementations.

namespace CodeFirstMVC.Models
{
    public class APIUser : AbstractUser
    {
        public String ApiKey { get; set; }
        public String PartnerName { get; set; }
    }
}

 

namespace CodeFirstMVC.Models
{
    public class ApplicationUser : AbstractUser
    {
        // Details related to typical Application Users
    }
}

 

 

The DBContext

The Entity Framework Code-First approach is to Build a DbContext class to replace the ugly old mapping layer. The Context acts as a transactional proxy between each Domain Entity and the Underlying Storage Implementation.

Here is the DB Proxy that we would use

namespace CodeFirstMVC.Models
{
    public class UserDbContext : DbContext
    {
        public DbSet<AbstractUser> Users { get; set; }
    }
}

Two things to note:

  1. The DbContext does not need granular mapping to sub-types ApiUser and ApplicationUser. This means, we can extend to our heart’s content and bypass mapping layers that are specific to the implementation.
  2. DbSet contains the Data Access methods generally needed for a CRUD (Create-Retrieve-Update-Delete) layer

Taking a peek at the DbSet, the approach of the proxy will become a bit more transparent

namespace System.Data.Entity
{
    public class DbSet<TEntity> : DbQuery<TEntity>, IDbSet<TEntity>, IQueryable<TEntity>, IEnumerable<TEntity>, IQueryable, IEnumerable where TEntity : class
    {
        public void Add(TEntity entity);
        public void Attach(TEntity entity);
        public TEntity Find(params object[] keyValues);
        public void Remove(TEntity entity);
    }
}

 

The UserManager and Test

Although the Entity Framework Code-First approach is designed to keep things lean-and-mean for us, I will never get away from the Manager approach as a Data Access Abstraction.

Traditionally, Software Developers would create an IUserManager and then have two implementations: (1) Actual controller code, and (2) Mock impl. for unit tests heavily leveraging dependency injection.

Since the DbContext is just a set of POCO’s mapped to the Store we are able to simply use Linq in a single implementation, relying on production/test configuration to tell the Entity Framework how to ‘map’ the data.

So, lets implement two simple tasks

  • ApplicationUser FindApplicationUserByName(String userName)
  • String GetPartnerForApiKey(String apiKey)

First, we need to setup our MSTest project to use SQLCE as the Store by adding the following to the app.config

<connectionStrings>
    <add name="UserDbContext" connectionString="Data Source=|DataDirectory|UserDbContext.sdf"  providerName="System.Data.SqlServerCe.4.0" />
</connectionStrings>

 

Note: the connectionString name by default should be set to the same name as the dbContext. If you do this, the Entity Framework needs no additional configuration.

Then, the MSTest class Implementation

namespace CodeFirstMVC.Tests.Managers
{
    [TestClass]
    public class UserManagerTest
    {
        public static String apiUserName = "Bill Paxton";
        public static String apiPartnerName = "Twitter";
        public static String apiUserEmail = "Bill@twister.com";
        public static String apiKey = Guid.NewGuid().ToString();

        public static String webUserName = "Kacie Grainger";
        public static String webUserEmail = "Bill@twister.com";

        /// <summary>
        /// Mock Database Initializer for the Unit Test Classes
        /// </summary>
        private class testDbInitializer : RecreateDatabaseIfModelChanges<UserDbContext>
        {
            protected override void Seed(UserDbContext context)
            {
                APIUser sampleApiUser = new APIUser();
                sampleApiUser.PartnerName = apiPartnerName;
                sampleApiUser.UserName = apiUserName;
                sampleApiUser.Email = apiUserEmail;
                sampleApiUser.ApiKey = apiKey;

                // Add my new Api User to the DbContext
                context.Users.Add(sampleApiUser);

                ApplicationUser webUser = new ApplicationUser();
                webUser.Email = webUserEmail;
                webUser.UserName = webUserName;

                // Add my new Web User to the DbContext
                context.Users.Add(webUser);

                // Commit the Adds on the DbContext to the Store
                context.SaveChanges();
            }
        }

        [TestInitialize]
        public void InitializeTest()
        {
            Database.SetInitializer<UserDbContext>(new testDbInitializer());
        }

        [TestMethod]
        public void FindApplicationUserByNameTest()
        {
            UserManager userManager = new UserManager();
            ApplicationUser applicationUser = userManager.FindApplicationUserByName(webUserName);
            Assert.IsTrue(applicationUser.Email == webUserEmail);
        }

        [TestMethod]
        public void GetPartnerForApiKey()
        {
            UserManager userManager = new UserManager();
            String result= userManager.GetPartnerForApiKey(apiKey);
            Assert.IsTrue(result == apiPartnerName);
        }
    }
}

 

Three important things to note

  • Database.SetInitializer<> is the Entity Framework way of seeding in data via the dbContext. For this test, I have provided the testDbInitializer which inherits a shipped Initializer
  • Database Initialization is static
  • Tests are decoupled from the dbContext through the UserManager

Running these tests will give us the full failure, so lets impl. the manager.

namespace CodeFirstMVC.Managers
{
    public class UserManager
    {
        public ApplicationUser FindApplicationUserByName(String userName)
        {
            UserDbContext context = new UserDbContext();
            var result = from user in context.Users.OfType<ApplicationUser>()
                         where user.UserName == userName select user;
            if (result.Count<ApplicationUser>() > 0)
                return result.First<ApplicationUser>();
            return null;
        }

        public String GetPartnerForApiKey(String apiKey)
        {
            UserDbContext context = new UserDbContext();
            var result = from user in context.Users.OfType<APIUser>()
                         where user.ApiKey == apiKey select user;
            if (result.Count<APIUser>() > 0)
                return result.First<APIUser>().PartnerName;
            return null;
        }
    }
}

 

In the Manager Implementation, get the particular DbSet<> Proxy from the DbContext as needed for your particular POCO.

For CRUD operations, simple follow the same pattern as defined in the testDbInitializer seed method.

 

image

 

ASP.NET MVC Usage

The Entity Framework DbContext actually decides how to interact with the Storage Provider at runtime, which means that all a developer has to do is change the providerName in the Connection String to work against a different store.

So, for this example, lets copy the same settings from the MSTest app.config into our ASP.NET Web.config.

<configuration>
  <connectionStrings>
    <add name="UserDbContext" connectionString="Data Source=|DataDirectory|UserDbContext.sdf"  providerName="System.Data.SqlServerCe.4.0" />
    ...
  </connectionStrings>
   ...

 

Just like in the Unit Test, we need to seed data into our relational store through a global Initializer. This is an appropriate task for the Application_Start event in the Global.asax

namespace CodeFirstMVC
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

        }

        /// <summary>
        /// Relational Store Initlializer Entry Point
        /// </summary>
        private class UserDbInitializer : RecreateDatabaseIfModelChanges<UserDbContext>
        {
            protected override void Seed(UserDbContext context)
            {
                APIUser sampleApiUser = new APIUser();
                sampleApiUser.PartnerName = "Twitter";
                sampleApiUser.UserName = "Bill Paxton";
                sampleApiUser.Email = "Bill@twister.com";
                sampleApiUser.ApiKey = Guid.NewGuid().ToString();

                // Add my new Api User to the DbContext
                context.Users.Add(sampleApiUser);

                ApplicationUser webUser = new ApplicationUser();
                webUser.Email = "todd@deepelement.com";
                webUser.UserName = "toddpi314";

                // Add my new Web User to the DbContext
                context.Users.Add(webUser);

                // Commit the Adds on the DbContext to the Store
                context.SaveChanges();
            }
        }

        protected void Application_Start()
        {
            // Seed the Database on app start-up
            Database.SetInitializer<UserDbContext>(new UserDbInitializer());

            AreaRegistration.RegisterAllAreas();

            RegisterRoutes(RouteTable.Routes);
        }
    }
}

All that is left now is displaying the data returned from the UserManager as defined via the tested API.

 

Create a typed MVC View based on the AbstractUser under the ~/Views/Home folder

image

Then, for the sake of the example, decorate the home controller with a User Action

 public ActionResult User()
 {
      UserManager userManager = new UserManager();
      return View("User", userManager.FindApplicationUserByName("toddpi314"));
 }

Run the application, navigating to ~/Home/User, to find the user listed

image

 

Conclusion

This simple scenario of Code-First using the Entity Framework 4 CTP hopefully exemplifies how the configuration based POCO mapping can be immediately beneficial for Test Driven Developers.

Although there are many more complex scenarios that are now trivial in other frameworks like NHibernate and Hibernate, the EF Team is working hard to collect feedback from the .NET community to build a great set of tools.

Please include your feedback at http://data.uservoice.com/forums/72025-ado-net-entity-framework-ef-feature-suggestions

 

Additional Resources

ScottGu’s Entry on Announcement

Enitty Framework Team: Data Annotations (Attributes) Available on Domain Model

Entity Framwork Team: Code-First EF Conventions