Monday, May 14, 2012

jQueryUI and ASP.NET Master Pages

Here is cool trick to save some time when using jQueryUI and ASP.NET with master pages. The thing that always seems to trip someone up is finding a control from the master page and trying to hit it with a jQuery call. When ASP.NET adds a control to the DOM and you are using master pages, the ID is actually changed from what you assigned in the designer. It seems to be fairly random and shouldn't be counted on for consistency or convention, aside from all of the randomness preceding the ID from the designer. After piddling around for a while, I did find something that will work. Consider the following code (This code assumes you have all of your links and css hooked up.):
<script type="text/javascript">
 
$(function ()
{           
  $('[id$=txtCal]').datepicker({
     showOn: "button",
     buttonImage: "../images/calendar16.png",
     buttonImageOnly: true,
     buttonText: 'Choose'
   }); 
}
</script>
By using the jQuery "ends with" selector ($=) I am able to find any control with an ID. So, by using this master page, ANY control that has an ID ending with 'txtCal' will be formatted to be a drop down calendar using jQueryUI. By using this sort of approach and following consistent naming conventions, you would be able to do most of your UI changes from your master pages, allowing for consistent theme style control over their implementation. This also opens the door for driving more jQuery behavior from the the master page.

Wednesday, May 9, 2012

Noteworthy Items From WCF Labs

Having moved on from the windows development aspect of the certification process and diving deeply into the inner workings of WCF, I noted some items worth mentioning.  These items cover some aspects of WCF that are new to WCF, some that are old but not adequately appreciated, and some that are seemingly relevant only to certification.  This section has been much more intense and in-depth than the previous one, and the labs can last up to a half day. The practice exams have 130-140 questions and the 3-day deep dive has consisted of 2 books totaling about 900 pages.  To date, here are some noteworthy WCF items and a short description of each.

ConcurrencyMode.Reentrant
When unable to rely on a well partitioned service layer, this setting can come in handy for preventing deadlocks and time-out errors from within a service call.  To put it at the most simplistic level, allowing re-entrant concurrency will allow the same thread to re-enter the same operation without waiting on itself to complete.  Sure, if you have followed good SOA guidelines all along, you would never need this one, but since in the real world, we have not, this could be quite useful.  In the case I outlined in my SOA discussion regarding logical distribution and the possibilty of BLL -> DAL - >BLL collisions, this could be a very good stop gap to keep your customers running while you work toward a more correct logical design.  This will avoid the deadlocks and timeouts caused by a single call colliding with itself withing an operation with this concurrency.

Throttling

Throttling can be a useful tool for regulating the number of calls or sessions at any given time.  Since allowing multiple concurrency is often required even though the operation may be long, the realistic possibility of resource overload can be avoided by simply throttling the number of calls or sessions.

<behaviors>
 <serviceBehaviors>
   <behavior name="throttleBehavior">     
       <serviceThrottling
         maxConcurrentCalls="20"
         maxConcurrentInstances="200"
         maxConcurrentSessions="10"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

This can be set based on realistic usage of the given service.  Sometimes, it may be better to have traffic waiting in a queue compared to having all clients fighting over resources.

Streaming
Streamed Message Transfer allows the service to stream back large result sets to the client without creating the entire object in memory prior to transport. This again could be a helping hand in an environment when server resources are being hogged and blocked by large amounts of data and traffic.

Discovery
New to .NET 4.0, discovery allows for services to be dynamically located by a client without any knowledge of the host address.  It basically allows services to broadcast their location and clients to search for them.  The obvious usage is for deployment to an unknown environment without the need for settings to be changed by non-technical users.  It can go much deeper than that.  This allows a client to search for an available service at each connection.  The dynamism here is again quite promising.  This means that you could configure fail-safe services and have clients dynamically connecting to the first available.

WCF Routing
New to .NET 4.0, routing is the ability to configure a generic soap service to be the 'gatekeeper' to the actual service being called.  For instance, a routing service can be used to roll your own load-balancing on a local install. The routing service can also be configured to allow service-based routing, content-based routing (e.g. filter message based on data and route to correct service), fail-over routing, and priority routing.  This is incredibly powerful and seems like WCF has given all the tools to build your service layer to be as scalable and dynamic as needed.

Default endpoints
New to .NET 4. While not the recommended idea, default endpoints are a nice way to ensure that all clients have the ability to interact with your services. Currently, if you try to host a service without any configured endpoints, the ServiceHost instance will throw an exception informing you of the need to configure at least one endpoint. With .NET 4, this is no longer the case because the runtime automatically adds one or more “default endpoints” for you, basically making the service usable without any configuration.

Exposing to Json
This one just struck me as cool.  You can allow your WCF service to respond in JSON or MessageContracts with some simple switching and decoration.  By decorating a service as follows:

 [ServiceContract]
    public interface ITestService
    {
        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/GetDataAsJson")]
        SomeData GetData();        
    }

and then adding a file named GetDataAsJson.svc with the following markup

<%@ ServiceHost Service="MultiService.TestService" 
                Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>

The service will begin to dynamically respond with Json or Contract using the same implementation.

There is much more to discuss, but this is a short list of items that have stuck in the forefront of my mind.

Sunday, May 6, 2012

MCTS Windows Development with .NET 4

The first certification I am pursuing is the MCTS in Windows application development.  Coming in with a few years of C# winforms development in hand, I thought this one would be fairly straightforward.  I soon realized that having in-depth exposure in my world doesn't always equate to having wide exposure in the rest of the world.  The expectations are high for this session.  The workload amounts to 12-13 hours a day between labs, studying and practice tests.  I have read a five hundred and eighty page text book in just over two days and have found that at least 65% of it has been fairly new territory.  The MCTS certification is heavily slanted to WPF.  It seems like Microsoft is pushing the technology toward this platform as the standard for development.  After having some time to delve into it, the reason becomes obvious.  The rich presentation layer that can be created on this platform is powerful, scalable and adaptable.  The xaml itself is not unlike any other markup, and if you can read and follow html, xml, etc., you will be fine reading through xaml and understanding the intent of the code.  What stands out to me regarding this platform is the inherent dynamism of the GUI itself.  The ease with which we can create a highly usable and intuitive interface is really quite impressive.  Take the following example (borrowed from the class):

    <Window.Resources>
        <ControlTemplate x:Key="ButtonTemplate" TargetType="Button">
            <Grid>
                <Ellipse Name="Ellipse1" Stroke="{TemplateBinding BorderBrush}"
         StrokeThickness="{TemplateBinding BorderThickness}">
                    <Ellipse.Fill>
                        <RadialGradientBrush GradientOrigin=".5, .5">
                            <GradientStop Color="Red" Offset="0" />
                            <GradientStop  Color="Orange" Offset=".25" />
                            <GradientStop  Color="Blue" Offset=".5" />
                            <GradientStop  Color="Yellow" Offset=".75" />
                            <GradientStop Color="Green" Offset="1" />
                        </RadialGradientBrush>
                    </Ellipse.Fill>
                </Ellipse>
                <ContentPresenter HorizontalAlignment="Center" 
         VerticalAlignment="Center"/>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter TargetName="Ellipse1" Property="Fill">
                        <Setter.Value>
                            <RadialGradientBrush GradientOrigin=".5, .5">
                                <GradientStop Color="LightCoral" Offset="0" />
                                <GradientStop  Color="LightSalmon" Offset=".25" />
                                <GradientStop  Color="LightBlue" Offset=".5" />
                                <GradientStop  Color="LightYellow" Offset=".75" />
                                <GradientStop Color="LightGreen" Offset="1" />
                            </RadialGradientBrush>
                        </Setter.Value>
                    </Setter>
                </Trigger>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter TargetName="Ellipse1" Property="Fill">
                        <Setter.Value>
                            <RadialGradientBrush GradientOrigin=".5,.5">
                                <GradientStop Color="Gray" Offset="0" />
                                <GradientStop  Color="LightGray" Offset=".25" />
                                <GradientStop  Color="Black" Offset=".5" />
                                <GradientStop  Color="White" Offset=".75" />
                                <GradientStop Color="DarkGray" Offset="1" />
                            </RadialGradientBrush>
                        </Setter.Value>
                    </Setter>
                </Trigger>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard>
                        <Storyboard AutoReverse="True">
                            <DoubleAnimation To="0" Duration="0:0:0.1"   
             Storyboard.TargetProperty="Width" />
                            <DoubleAnimation To="0" Duration="0:0:0.1" 
             Storyboard.TargetProperty="Height" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Template" Value="{StaticResource ButtonTemplate}" />
        </Style>
    </Window.Resources>

This creates a button template that applies a style (very ugly) and behavior that can be associated with any button.   By including the following style block and associated setters, the template is automatically applied to all buttons contained in the current window.

<Style TargetType="{x:Type Button}">
  <Setter Property="Template" Value="{StaticResource ButtonTemplate}" />
</Style>  

If I wanted to apply this template and style to the entire application, I would simply move these snippets to the app.xaml.  Another level of dynamism comes by allowing you to link to external xaml files as application resources and swap them.  So, not only could you customize the look and feel of the application, you can dynamically customize the inherent behavior of elements at the application level.  There is a ton more to get into with this kind of thing, and we will at a later date.  Other possibilities include, command triggers, gestures, framed animations and much more.  It has been very interesting to date and I will bring back some renewed focus on pushing the ui envelope within our applications.

Thursday, April 26, 2012

SOA Discussion

SOA is a constant topic of conversation these days and has become a mindset for people trying to architect systems that are available, dependable, scalable and maintainable.  The trick of discussing SOA at a high level or simply stating that it is your goal is that SOA itself is not easily definable when placed in the paradigm of any individual business or system.  SOA is a conceptual methodology or a philosophy of sorts.  This seems to contribute to the possibility of having your project team actively pursuing a common goal, of which they each have their own interpretation.  As this becomes more of a daily task in reality and less of a mental exercise, it seemed like a good time to lay out what this architecture means to me.  In my mind, SOA can be defined as an architectural means to build a system consisting of many autonomous and focused services.  To architect in SOA you have to start by defining the level at which you want the system in question to be integrated.   Since any business system can be comprised of many smaller systems, on many platforms with many different implementations, it is paramount to focus on an integration interface.  As I have heard said, and love to repeat, "You have to eat your own dog food."  Basically, rather than creating a system and then opening up integration, the systems themselves have to be a packaged consumption of service integration. Rather than get into a semantic argument about the exact definition of a service, for the sake of this discussion, let’s assume that a service is defined as a program that is interacted with via message exchanges.   Services must be designed to be highly available and scalable.  When I speak of being scalable, it is to infer the need to have a consistent and constant means of interacting with the service itself.  The configurations and aggregations of the service are where you should scale out and customize to meet an individual name.  But at the end of the day, the core service should be small, focused and consistent.  It should perform the advertised action entirely and exclusively. This is the Single Responsibility aspect of the SOLID principles, which should be followed as a rule.  Being singularly focused allows for our services to come together to form a loosely-coupled infrastructure, which positions us for the aforementioned scalability and maintainability.  Systems architected with this philosophy result in a network of logical processes and functions that are no longer held prisoner by existing infrastructure or large project migrations.  This allows for individual services to be updated, replaced, rewritten or otherwise reinvented without a direct impact to any integrating processes.  As long as all service interfaces remain consistent and constantly rely upon a messaging system for interaction, the actual logic and heavy lifting of these services becomes completely abstracted behind the interface messages.  This, to me, is the heart of the matter.  Every service, every process and every system, at this point, should be interacting primarily with an eternal set of interface messages with a seeming disregard for the entity with which it is communicating.

The Four Principles of SOA
A generally accepted principle of SOA is the adherence to the four principles of SOA.  We will go through them one by one and try to get to the root of what they mean in spirit and in actuality.

Boundaries Are Explicit
A boundary is really just the dividing wall between a public interface and internal implementation. That concept is fairly straightforward and should be easily grasped.  It is vital that this is followed to allow for dynamic relocation of services, etc.  A good way to grasp this principle is to make sure that a consumer of a service has absolutely no insight into the implementation of the internal process.  The consuming entity should have no control of the performance of the services being consumed.  I would like to take this a little bit further and begin to talk about bidirectional crossing of tier boundaries, but in order to do so, we need to define the terms ‘layer’ and ‘tier’.  When we talk about these items, understand that a ‘layer’ is a logical grouping of code and/or processes.  For instance, a DAL or data access layer is a grouping of functions that interacts with a dataset of one kind or another.  The DAL should provide services/functions that encapsulate all interaction with the dataset to ensure all rules are consistently met and any policy enforcement can happen in a dependable manner.  This has absolutely nothing to do with physical location and arguably can share process space with other layers depending upon the facts of a given situation.  A ‘tier’ on the other hand implicitly indicates a physical location.  In other words, a tier contains one or more layers.  A good rule of thumb is that no process should interact with another process any further out (being toward the consumer) than the tier at which it is running.  This rule is not broken with push notifications, update messages or callbacks; those are different types of communication and are completely acceptable.  This rule ensures that your objects are designed with the appropriate level of encapsulation in mind. For example, consider the following 3 tiers and their logical format.  GUI, BLL and DAL.  The GUI will be the consumer of a service on the BLL, UpdateEmployee.  BLL::UpdateEmployee will in turn be a consumer of DAL::UpdateEmployee.  The argument comes that the Employee entity could have a related EmployeePicture record.  The quick and dirty reaction is to have DAL::UpdateEmployee update the EmployeePicture record directly against the dataset.  A later revised system requirement is that every Employee should have a 1:* relationship with EmployeePicture.  So, the developer creates a BLL::UpdateEmployeePicture along with DAL::UpdateEmployeePicture.  Problem solved.  A consumer can create Employees and EmployeePictures interchangeably.  Another revision requires that every Employee must have a default picture.  So, adhering to good OOP principles, the developer has DAL::UpdateEmployee consume BLL::UpdateEmployeePicture to create the initial record.  This is where we start getting into all kids of trouble.  The tier communication rule is broken. While this is innocuous enough right now, when the next design change requires the Employee record to be updated with a modified date of today each time an EmployeePicture is created, it becomes an issue.  So what do you do?  You can’t have BLL::UpdateEmployeePicture call DAL::UpdateEmployee since it could very likely be the parent origin of the current context.  You can’t have DAL::UpdateEmployeePicture call DAL::UpdateEmployee, since it is likely the origin of this context.  The model is broken.  The ideal methodology here is to have the DAL functions do nothing more than they say they do and have the BLL services be aggregate calls to the DAL.  All synchronous consumption flows inward and is never intermixed across tiers.

Services Are Autonomous
I like to read this one as ‘Do what you say and say what you do, completely.’ A service should perform the task it is designed to perform and never more or less.  The entirety of the process should be documented so that all service consumers are acutely aware of the process intent.  These services should be completely independent of the consuming code as well as any services with which they interact internally.  This allows for a service to be versioned and deployed independently of interacting processes.  This also creates the need for a rule to follow in regards to this principle.  Once and interface is deployed and live consumption is plausible, the interface can’t be modified.  Interfaces can be added and logic abstracted at this layer, but the interface, once published is in fact eternal.  You should also always assume a worst case scenario from the consumer of the service.  This means, don’t count on the data to be valid; don’t assume all values are correct; and don’t assume that the developer of the consuming process has any idea what your service is expecting.  This includes the dependency of functions being called in a certain order to create and maintain scope level variables.  All things that need to be known by a service should either be inherently internal or provided by the consumer.  Create your rules, enforce them internally and raise exceptions when they are not met.  This includes interaction with other services that may not be available.  Never assume that all interactions required will be available.  If the service interacts with something that is currently unavailable, you should have a fail-safe in place.
 
Services Share Schema and Contract, Not Class
Service consumption should be based on contracts, schemas or policies. A good way to stay agnostic in this regard is to communicate using SOAP or XML schema-based messages.  This makes both language and platform a non-factor in your service consumption.  While this is highly dependent upon the need to be available outside of known technologies and platforms, it is always a good mental exercise at design time.  A contract must remain stable over time.  Again, once deployed they must be eternal.  That is probably the most difficult part of this rule.  But, I always like to think of a very simple example for this sort of philosophy.  Consider a light bulb socket.  Light bulbs themselves have changed over time, as have wiring standards, breakers, building codes, etc.  But, a light bulb socket has maintained interoperability with all of these items by simply interacting with electricity on one side and a static interface to a light bulb on the other.  It has no visibility, nor concern with the inner workings of the light bulb, nor does it care about the circuitry of the room in which it is housed.  Its interface, or contract if you will, stays constant and simply works with any input/output that interacts with the known interface.  Always adhere to a good division of internal data and external data.

Service Compatibility Is Based Upon Policy
Honestly, this one is tricky.  I have researched this and the best personal example I can give is how you would use a WCF OData service and a QueryInterceptor to resolve a local security policy.  The intent is obviously to have external, possibly machine-readable policies, governing access and compatibility to certain configurations and aspects of your services.  I struggle with finding real-world examples.  I like using the QueryInterceptor as a good and simple illustration.  With this, you can check the context of the caller and decide whether or not a user in this context should be able to access the query that has been requested.  This seems highly-scalable and very powerful since it completely decouples the services implementation from the policy governing its access.  I think this one will become more useful over time as more and more services adhere to the first three aspects of this article.

Conclusion
Overall, it seems that SOA is a great target to have for architecting a system and should be kept as a standard at all levels.  It will serve to position your system for future growth while ensuring your sanity while trying to balance maintenance and advancing projects.

Tuesday, April 17, 2012

Creating and Consuming RESTful WCF Data Services

I have been reading/researching REST WCF Data Services, OData, creation, consumption, etc.  This methodology is a very useful basic construct.  By using the entity framework within Visual Studio 2010, I created a basic blog/atom/rss feed project in order to get my hands around it. 
Here is an overview of what I found:

Entity Framework
The entity framework is very powerful out of the box.  It allows you to create models that are directly tied to your database and queryable using LINQ.  It basically infers your data objects as entities, and creates your basic CRUD operations coupled with them.
It will infer your schema by either creating from an existing database or by creating a database from your entity design.  For the purpose of this exercise, I created an entity and then created a database from the entity layout.  I started by creating a new ADO.Net Entity Data Model in my project.



Then, I laid out my elements with the needed relationships:


The cool part here was adding these values as scalar or navigation properties.  The navigation properties infer the foreign key relationship and allow you to do 1:1, 1:* or *:* for the multiplicity.  It also infers the referential relationship for integrity.

After completing the entity model, I simply RMC and selected 'Generate Database from Model...'.  This walked me through connecting to the serve instance and credentials.  I had the option of creating a new catalog or appending to an existing one.  I chose to create.  This step created the catalog and generated a SQL for creating the schema with all constraints.  At this point, I ran the SQL and the entire database was created.


Creating the WCF DataService
This part is where it gets crazy intuitive and easy.  First thing you have to do is create a WCFDataService.

Then, I replaced the TODO code with the basics to get lists


public class PTCFeedService : DataService<PTCFeedsContainer>  
{  
    // This method is called only once to initialize service-wide policies.  
    public static void InitializeService(DataServiceConfiguration config)  
    {  
      config.SetEntitySetAccessRule("Feeds", EntitySetRights.All);  
      config.SetEntitySetAccessRule("Entries", EntitySetRights.All);  
      config.SetEntitySetAccessRule("Tags", EntitySetRights.All);  
      config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;  
      config.UseVerboseErrors = true;  
     }  
}  

At this point, I am able to compile and run.  I have automatically generated some basic REST Services along the way.  What this gives me is the ability to query from a uri for a plural of all entities.  A quick informative query is to get the meta data from the service.  (http://localhost:62368/PTCFeedService.svc/$metadata)


<edmx:Edmx Version="1.0">  
    <edmx:DataServices m:DataServiceVersion="1.0">  
     <Schema Namespace="PTCFeeds">  
      <EntityType Name="Feed">  
       <Key>  
        <PropertyRef Name="FeedID"/>  
       </Key>  
       <Property Name="FeedID" Type="Edm.Int64" Nullable="false" p8:StoreGeneratedPattern="Identity" p9:SetterAccess="Public"/>  
       <Property Name="Name" Type="Edm.String" Nullable="false" MaxLength="40"/>  
       <NavigationProperty Name="Entries" Relationship="PTCFeeds.FeedEntry" FromRole="Feed" ToRole="Entry"/>  
      </EntityType>  
      <EntityType Name="Entry">  
       <Key>  
        <PropertyRef Name="EntryID"/>  
       </Key>  
       <Property Name="EntryID" Type="Edm.Int64" Nullable="false" p8:StoreGeneratedPattern="Identity"/>  
       <Property Name="Created" Type="Edm.DateTime" Nullable="false" p8:SetterAccess="Public"/>  
       <Property Name="Title" Type="Edm.String" Nullable="false"/>  
       <Property Name="Content" Type="Edm.String" Nullable="false"/>  
       <Property Name="FeedID" Type="Edm.Int64" Nullable="false"/>  
       <Property Name="Modified" Type="Edm.DateTime" Nullable="false" p8:SetterAccess="Public"/>  
       <NavigationProperty Name="Feed" Relationship="PTCFeeds.FeedEntry" FromRole="Entry" ToRole="Feed"/>  
       <NavigationProperty Name="Tags" Relationship="PTCFeeds.TagEntry" FromRole="Entry" ToRole="Tag"/>  
      </EntityType>  
      <EntityType Name="Tag">  
       <Key>  
        <PropertyRef Name="TagID"/>  
       </Key>  
       <Property Name="TagID" Type="Edm.Int64" Nullable="false" p8:StoreGeneratedPattern="Identity"/>  
       <Property Name="Name" Type="Edm.String" Nullable="false"/>  
       <NavigationProperty Name="Entries" Relationship="PTCFeeds.TagEntry" FromRole="Tag" ToRole="Entry"/>  
      </EntityType>  
      <Association Name="FeedEntry">  
       <End Role="Feed" Type="PTCFeeds.Feed" Multiplicity="1"/>  
       <End Role="Entry" Type="PTCFeeds.Entry" Multiplicity="*"/>  
       <ReferentialConstraint>  
        <Principal Role="Feed">  
         <PropertyRef Name="FeedID"/>  
        </Principal>  
        <Dependent Role="Entry">  
         <PropertyRef Name="FeedID"/>  
        </Dependent>  
       </ReferentialConstraint>  
      </Association>  
      <Association Name="TagEntry">  
       <End Role="Tag" Type="PTCFeeds.Tag" Multiplicity="*"/>  
       <End Role="Entry" Type="PTCFeeds.Entry" Multiplicity="*"/>  
      </Association>  
     </Schema>  
     <Schema Namespace="PattersonTechCenterFeeds">  
      <EntityContainer Name="PTCFeedsContainer" p7:LazyLoadingEnabled="true" m:IsDefaultEntityContainer="true">  
       <EntitySet Name="Feeds" EntityType="PTCFeeds.Feed"/>  
       <EntitySet Name="Entries" EntityType="PTCFeeds.Entry"/>  
       <EntitySet Name="Tags" EntityType="PTCFeeds.Tag"/>  
       <AssociationSet Name="FeedEntry" Association="PTCFeeds.FeedEntry">  
        <End Role="Feed" EntitySet="Feeds"/>  
        <End Role="Entry" EntitySet="Entries"/>  
       </AssociationSet>  
       <AssociationSet Name="TagEntry" Association="PTCFeeds.TagEntry">  
        <End Role="Tag" EntitySet="Tags"/>  
        <End Role="Entry" EntitySet="Entries"/>  
       </AssociationSet>  
      </EntityContainer>  
     </Schema>  
    </edmx:DataServices>  
   </edmx:Edmx>  


Binding to asp.net
At this point, your service is ready to go.  Add a reference to the service using the uri as you would add a normal WCF service. Do not use web reference in this case.  Binding it to a grid control is almost too simple.


PTCFeedSvcRef.PTCFeedsContainer feedSvc =
  new PTCFeedSvcRef.PTCFeedsContainer(new Uri(@"http://localhost:62368/PTCFeedService.svc/"));   
GridView1.DataSource = feedSvc.Feeds;  
GridView1.DataBind();  


This is a simple example, but should illustrate how powerful these concepts can be.  Feel free to shoot me any questions or comments.

Saturday, April 14, 2012

Coalesce and Inline Operators

As part of a platform review, I have been seeing a lot of code lately that has been in production for a while.  I know that sometimes people are just creating the code they know how to create and making the project run.  That is all good.  Sometimes it is good to try and learn a better way way to do some very basic things.  I know that personally the following options make code a bit more easy to follow and maintain.

Coalesce
There are a lot of long if statements that seem to be looking for the first usable value. (this is a composite of the idea...)


if (value1 != null)  
    variable = value1;  
else if (value2 != null)  
    variable = value2;  
else if (value3 != null)  
    variable = value3;  
else  
    variable = DefaultValue;  

Just to simplify and make more readable, try using the ?? (coalesce) operator.  Notice the nullable type restrictions, etc.


variable = value1 ?? value2 ?? value3 ?? DefaultValue;   


Inline If
Here is another one (again, just a composite)

if (something == somethingelse)  
  value = "1";  
else  
  value = "2";     

try making this one line, more readable.

value = (something == somethingelse) ? "1" : "2";      


I know that these are some basic ideas, but judging by the code bases I have been checking out, they are not widely used.  Perhaps, looking into some of these items as best practices would be beneficial.