As architects, designers, and developers create the first wave of Silverlight applications, one thing has become apparent. We need to give some thought to how the use of Silverlight in the presentation layer changes the way we architect, design and code applications. Some popular patterns that that have served us well in the past need to be revisited.
I thought that I’d use this forum to highlight some of the challenges that many early Silverlight users face, and invite comments or suggestions from people working with or thinking about the same challenges.
This post is related specifically to the topic of code reuse and redundancy. In future postings, I hope to take up other similar topics.
With smart development tools and knowledge of best practices and enterprise design patterns, we seem to have been quite successful in maximizing reusability and minimizing redundancies in code. So, why is code reuse and redundancy important again?
Two reasons –
1. Silverlight applications cannot reference .NET class libraries. The same constraint applies to the reverse -.NET applications cannot reference Silverlight applications.
2. The use of Silverlight often requires developers to find the right balance between code reuse, maintainability and performance.
Let’s look these two points in more details.
Silverlight Assembly References
Silverlight applications cannot reference .NET class libraries. The same constraint applies in reverse -.NET applications cannot reference Silverlight applications.
This basically rules out the development of class libraries with common reusable logic to be used by both .NET and Silverlight applications.
If a developer coded common math routines that need to be accessed by a Slverlight application and a .NET application, they may end up duplicating the exact same code in two different class libraries.
Let’s take a more realistic scenario where a developer creates aspx pages with embedded Silverlight applications. Now suppose that several Silverlight controls and aspx pages (read code behind) need to access the same WCF service. It would be ideal if the developer could create one service agent class that contains the necessary web reference, the code to invoke the service, and a common API that can be used by all Silverlight applications/ controls and .NET applications that need to consume the Web service. This would ensure that Web service reference and the code to invoke the service exists in only one place.
However, because of the fact that Silverlight and .NET assemblies cannot reference each other, developers may have to develop two service agents with the exact same code and Web service references.
Taking this scenario forward, assume that we need entity translators to translate the types exposed by the proxy to business entities used internally in the Silverlight and ASP.NET applications. Again we will need to develop different translators with identical code.
So, what’s the solution? Using source control features to link class files in different Visual Studio projects? Creating scripts that copy/ synchronize different class files? Would you write a slightly intelligent script that would change the namespaces appropriately. These all work to some extent, but are far from an ideal solution. Me? For now, I’m living with duplicate code in different class files.
Code Reuse vs. Performance and Maintainability
Silverlight applications are downloaded to the user’s browser. This puts an extra burden on developers to keep the size of Silverlight applications as small as possible. You may think that the discipline that was required from developers of Web pages to keep the size of pages small is the same as what would apply to developers of Silverlight applications. Well, yes and no. Silverlight provides design options that were not available to ASP.NET developers that force them to find a balance between code reuse and performance and maintainability,
Consider a Web application with a Silverlight control that access WCF services. There are several ways of designing this application. I think the two design options that most of us will consider are:
a. Encapsulate the presentation logic as well as logic for accessing Web service in the Silverlight application. The business logic and business entities, if they exist, will also be part of the same Silverlight assembly.
b. Encapsulate the presentation logic in a Silverlight application. Create separate Silverlight class libraries for business components, business entities, and service agents. This approach allows common logic to be used by more than one Silverlight application.
Both approaches have their advantages and disadvantages.
Approach a provides better performance, a much leaner Silverlight application, but limited code reuse. Another Silverlight application in the same Web application may contain the same Web service reference an entity definitions.
Approach b provides a layered application architecture and allows code reuse. However, it increases the number of the in-package and/or on-demand assemblies that need to be downloaded by the user’s browser. Additionally, some of these assemblies may contain code that is not used the executing Silverlight application, e.g. a service agent class that calls a Web service used by a Silverlight application or control on a different page.
An important point to note here is that if we applied something similar to approach b to an ASP.NET application, the common assemblies would live on the Web server or application server depending on how it was deployed. They would never be a part of any discussion related to page size or internet bandwidth of end-users.
When choosing between approaches a and b (and others), we need to consider the following very carefully:
- What is the right balance between code reuse, performance, and maintainability?
- Should we introduce layered architecture and object oriented design concepts in Silverlight applications with the same rigor as we do while developing server components, just because the platform allows it?
After writing this post, I realize that it contains more questions than answers. Actually, it contains no answers. But like I said, the purpose of this post is to invite comments and views on this topic from readers.