Archive for the ‘Silverlight’ Category

Basic architecture of an ASP.NET / Silverlight web application

An important aspect of web development is choosing the right application architecture or framework, one that is flexible, easy to maintain and well understood by its developers.

The (ASP) .NET framework already offers a lot of built-in features which greatly reduce the overhead of common programming activities, and a content management system delivers out-of-the-box components and back-end functionality.

When it comes to custom development, it is of course the developer’s responsibility to apply best coding practices and common design patterns when and wherever possible, preserving high flexibility and maintainability in the application’s overall architecture.

Having this said, I would like to share with you a simple n-tier approach which is currently being implemented in one of our ongoing projects. As the framework fits the project, in this particular case there is no need for a CMS. Without going into too much detail, the use-cases indicate the need of data storage and retrieval (CRUD operations on a few persistent objects), email notification, dynamic generation of images and (multi-lingual) localization support.

An ASP.NET web application hosts 2 Silverlight features which provide a media player and a deep zoom component. Both the web and Silverlight applications need to access common business objects and a persistence mechanism, albeit in different use-cases.

Let’s take a closer look at the framework:

The application’s main class library, storing all business objects and business logic provides a single point of access for client applications: a Façade object. The Façade implements a clear interface for common tasks, while hiding the actual implementation.

As you may or may not know, a Silverlight application does not have direct access to a class library, but rather makes asynchronous calls to one or more (web) services. Great progress is currently being made to ease this challenge for developers (WCF RIA Services and ADO.NET data services) but we have chosen to use a more classic approach by setting up a WCF service. Much like the Façade, this service provides a clear interface for common tasks, although limited to the tasks required by the Silverlight applications. However, the actual implementation still resides in the Façade enhancing the solution’s flexibility (i.e. some tasks may be shared with the web application).

The persistence mechanism is abstracted by a data access object or DAO referenced only by the Façade, greatly reducing any dependencies. Much unlike the active record pattern which provides business objects with CRUD operations, the DAO provides these operations for a subset or all business objects.

Some extra hints & tips:

  • As you may have noticed, there is still a strong dependency between the Façade and the DAO. This dependency can easily be overcome by dependency injection (i.e. by using the Spring.NET framework, and injecting the proper DAO at runtime by means of configuration)
  • Although this example mentions just one façade and DAO, it is recommended to set up multiple instances, each encapsulating separate units of logic or data stores. Facades can easily be set up to interact with each other, and a DAO is commonly used to abstract a single data store.
  • Façade and DAO tend to grow large as they often encapsulate the implementation of large units of work. Implementing them as a singleton greatly reduces performance overhead when consumption increases.
  • By letting persistent business objects inherit from a base entity object the DAO can provide generic methods for CRUD operations, and so can the Façade
  • By unit testing against the Façade, you are able to test most (if not all) of the business logic

Some code fragments:

Facade & DAO interfaces:


public interface IBusinessFacade

{

IList<Company> SearchCompanies(CompanySearchCriteria criteria);

Company GetCompanyById(string companyId);

IList<Employee> SearchEmployees(EmployeeSearchCriteria criteria);

IList<Registration> SearchRegistrations(RegistrationSearchCriteria criteria);

bool SaveRegistration(Registration r);

bool GenerateDeepZoomImage(DeepZoomImage img);

bool DeleteRegistration(Registration r);

}

public interface IBusinessDao

{

T GetEntityById<T>(String id) where T : Entity;

IList<Company> SearchCompanies(CompanySearchCriteria criteria);

IList<Employee> SearchEmployees(EmployeeSearchCriteria criteria);

IList<Registration> SearchRegistrations(RegistrationSearchCriteria criteria);

void SaveRegistration(Registration r);

void DeleteRegistration(Registration r);

}

A persistent business object:


[Serializable]

[DataContract]

public class Employee : Entity

{

[DataMember]

public string FirstName { get; set; }

[DataMember]

public string LastName { get; set; }

[DataMember]

public string Email { get; set; }

[DataMember]

public string Phone { get; set; }

[DataMember]

public Company Company { get; set; }

}

The WCF Service interface:


[ServiceContract]

public interface ISLService

{

[OperationContract]

IList<Company> SearchCompanies(CompanySearchCriteria criteria);

[OperationContract]

IList<Employee> SearchEmployees(EmployeeSearchCriteria criteria);

[OperationContract]

IList<Registration> SearchRegistrations(RegistrationSearchCriteria criteria);

}

Silverlight application code calling the service:


protected void SearchCompanies()

{

try

{

SLServiceClient client = new SLServiceClient();

client.SearchCompaniesCompleted += new EventHandler<SearchCompaniesCompletedEventArgs>(SearchCompaniesCompleted);

client.SearchCompaniesAsync(new CompanySearchCriteria() { NameLike = "These Days" });

}

catch

{

// ..

}

}

A sample unit test written against the DAO:


[TestMethod]

public void GetEntitiesById()

{

var mockReg = MockFactory.Instance.CreateMockObject<Registration>();

BusinessDao.Instance.SaveRegistration(mockReg);

var regById = BusinessDao.Instance.GetEntityById<Registration>(mockReg.Id);

Assert.IsNotNull(regById, "Unable to retrieve registration by id");

var employeeById = BusinessDao.Instance.GetEntityById<Employee>(mockReg.Employee.Id);

Assert.IsNotNull(employeeById, "Unable to retrieve employee by id");

var compById = BusinessDao.Instance.GetEntityById<Company>(mockReg.Employee.Company.Id);

Assert.IsNotNull(compById, "Unable to retrieve company by id");

BusinessDao.Instance.DeleteRegistration(mockReg);

}

Going Microsoft all the way

During this last week we painted ourselves blue and donned our Microsoft caps. Just so you get the gist; we launched a Silverlight 3 project, we created an open source Silverlight component (that will thoroughly rock your socks ;) ), we hosted a besug event and went to Remix09 (we even ended up on the big screen during the keynote! – we still don’t know how that happened).

logo_td_ms

mslogo-1

Familie meerdijk

Our first Silverlight 3 project and a massive hit to boot. The project was headed by These Days Amsterdam for Microsoft Netherlands. They wanted to show the public how Office can be useful in day-to-day situations so we gave them “Familie Meerdijk”. The average
Dutch family who live their lives and bump into problems on the way. And whaddaya know… Office offers to solve them!

To be very honest… I myself am a huge Office 2007 fan, can’t and won’t live without it. Is this shameless promotion? Maybe… but I just love it that much!

The “Familie Meerdijk” project uses a lot of 3D animations so it was a real adventure to make this work, you can read more about how we got alpha channel in WMV video’s to work.

Maybe you should just head on over to Familie Meerdijk yourself to see it all in action.

SISTR

SISTR is a Silverlight component we made together with our partner Ventigrate. It’s a sIFR replacement that allows you to use rich typo graphics in your websites. Just an alpha version for now but we’re actively working on putting out a more stable release. More info about this project (+ examples, download, …) can be found on http://www.sistr.it

Arturo Toledo @ These Days

Last Monday Arturo Toledo, Product Manager at Microsoft for the UX Platform & Tools, visited the These Days offices for a session with the Belgian
Silverlight user group. The session was about Sketchflow (Expression Blend), a very cool tool that allows you to easily create wireframes using Microsoft’s Expression Blend. This way we had some upclose quality time with Arturo and damn, I for one, am now a totally brainwashed Sketchflow lover :) It was very nice to see what Sketchflow was all about and have some face2face moments with Arturo.

Some pictures of the event:

_DNF8156 _DNF8182 _DNF8179
_DNF8180 _DNF8171 _DNF8169
_DNF8166 _DNF8162 _DNF8163

Remix 2009

Last Tuesday Microsoft also organised the Remix 2009 event. We attended the event with four These Days people. What all the agencies have been saying for a while now has been re-confirmed by Microsoft; UX is a super important (if not the most important) aspect of your project… That’s why we, at These Days, also spend a lot of time and effort on getting this right. Big props for our four UX experts! (Who are now also planning on giving Sketchflow a try! :-) )

But of course we not only enjoyed the UX tracks, the developer tracks were also very inspirational.

The highlight of the day, for us, was the keynote though. It was nice to see which direction Microsoft is planning to go in the future and to hear about other companies’ usage of Microsoft technologies and even see some demos.

And just to scare everybody away I was also on the big screen in one of the movies.

IMG_0627

Some more pictures from the Remix can be found here.

Guest blogpost: Silverlight 3 and pixel shaders

Guest blog post by Stefan Van Camp from Ventigrate.

While I was working on at project here at These Days I ran into an opportunity to use one of the new Silverlight 3 features, custom built pixel shaders! The specific reason why we needed pixel shaders was because These Days wanted to use Alpha Channel encoded video with Silverlight. Of course, since Windows Media Video (.wmv) does not support alpha channels, the media stream used in the project would need to use pixel shader in order to filter out a predefined color.

It soon became clear to me that there was no simple answer to the question “Which pixel shader will give the best result?”. Some people claimed the Synergy effect provided the best results, other people referred to the shader from the WPF effects library, some even wrote their own shader… After having tried a couple of different methods I wasn’t completely pleased with any of the results they gave me. And therefore, since I had nowhere else to turn, I solicited Microsoft for help via Katrien De Graeve – Microsoft developer evangelist.

Microsoft’s explanation for the poor performance of the pixel shaders was that the shader’s calculations were based on the RGB values of the color that needed to be filtered out. They suggested using the HSV values of the color. This technique proved to be a significant improvement over the other shaders, but it still was not perfect. Green lines on the sides were still showing and wherever the video had a motion blur effect, the background color wasn’t filtered out.

Obviously, the first part of an acceptable solution was removing the motion blur effect from the movies (which were rendered 3D animations with effects from After Effects). Once we had a new render of the movie, we retested with the new HSV shader Microsoft had delivered and immediately noticed the decrease in green matte. Now we had only the green around the subject edges to worry about.

Because pixel shaders perform their ’shading’ by calculating a given color value to another value pixel by pixel, I got the idea of increasing the number of pixels that the movie would feed to the shader as a logical consequence. Since Expression Encoder didn’t seem to provide any means of increasing the amount of pixels in the form of changing a “dpi” property or something, I decided to encode the source movie at twice the dimensions of it’s original size. In my test case my movie was 856×806 big, I encoded it at 1600×1432 to make at least the width of the movie a nice round number. When I used this movie in my Silverlight project using the original dimensions of the movie (otherwise encoding to increase the scale had no point), the results were more than satisfying. The green contours where almost all gone, only people who actually knew to look for green edges would occasionally be able to spot one. Taken into account that most people don’t hug their screens and look at the movie over and over again, this technique proved to deliver a satisfying result that can actively be used in Silverlight applications using the correct shader.

I am, however, aware that at a certain point in the future, some bright mind will think up a shader that’s absolutely perfect. But since mathematics and creating shaders aren’t really my cup of tea, I will leave that to someone else. In the meantime, I believe we’ve come up with an acceptable temporary solution which will satisfy most of your clients.

One remark though: exaggerating the dimensions will have a negative impact on the playback performance in Silverlight. Depending on your system’s specifications you will run into performance issues sooner or later. The best method to find the correct dimensions for your target audience is trial and error I’m afraid. Make sure to test your application on a less competent machine.

On a side note, I would like to point out one bug I encountered while applying these shader effects to the media elements. Most of the time there will be a thin line surrounding the element. I don’t know whether this is caused by a bug in the shader or if the effect has an adverse reaction on the media element. In any case, you can work around this problem by simply setting the clip property of the media element to remove those ugly lines.

Resources: