Windows 8 Developer Preview
Dashboard
Windows Explorer
The new Windows Explorer uses the Office 2010 Ribbon
Internet Explorer 10
Internet Explorer 10 offers a new ‘chrome-less’ mode.
Icons on the bottom bar are called ‘Charms’
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
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
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.
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.
Next, Add the Entity Framework CTP Binary dependency to the CodeFirstMVC project
Running CodeFirstMVC at this point would show the default web content
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:
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:
- 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.
- 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.
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
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
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



