Sunday, October 30, 2011

The ORM duo: NHibernate and the Fluent NHibernate


I was travelling to my native place when I came across few interesting people with whom interaction was very cute, though very short. The one amongst them was the bus conductor who was punching the tickets for the passengers. The ticket needs to be punched on specific numbers before it is given to any passenger. The conductor probably uses some meaningful mappings to assure the passenger about their journey details and payments. Though the passenger is not aware about the mappings, except their payment details, they are assured their payment has been noted in the database and a receipt is delivered back to them. The mappings are cryptic so as to reduce the misuse of the same ticket for the different journey.


NHibernate is the analogy. Before the existence of ORM tools the developer had to write the SQL statements manually to interact with the database. The organization also had to hire specialized SQL developers, apart from application programmers, to take care of generating database interactive layer for the application. The programming paradigm for both the technologies is very different. This differences gave rise to creation of ORM tools.

The paradigm of using ORM tools for developing database applications is widely accepted due to ease of the development of the database products. ORM tools helps the software developer to interact with the database using the syntax of the programming language. These tools forms the generic DAL layer for different types of database applications thereby abstracting the database centric code from the application developer. The application developer need not be aware of PL/SQL to interact with the database but instead of it, the ORM takes care of generating database specific code as per the code written by the application user using the ORM tool. The following diagram shows the entities and the database tables in the system. I will show the code snippets more than write-ups for this post.



NHibernate is the open source ORM tool which takes care of the code generation for object-relational mappings. This tool works on the concepts of mappings which are stored in XML format. The mapping files are embedded into the assembly and is used to map POCO objects to the database objects at runtime. Typically, the mapping files often contains the map of POCO objects and the database objects with their relations.



The mapping files are very cumbersome to create and maintain and hence the developer may tend to make a lot of mistakes while writing the mapping files manually. The task of writing the mapping files are often taken away from the developer and pushed to the ORM veteran. This triggered the need for creating the custom library which takes care of mapping the domain model with the database without suffering from the hassles of writing the XML files.


The fluent NHibernate is the library which takes care of configuring NHibernate assemblies to work easily with your application code. The library mainly contains wrapper functions that takes care of configurations and mappings of the nHibernate library functions without having to create mapping files manually (a wizard like Harry Potter).



Let's discuss the process of creating the entities, their mappings and configuration using fluent NHibernate.


Entity:



The entity is the plain C# class with all the properties marked as virtual. The entity should have a unique identifier (Id) to uniquely identify itself.


Mapping:



The class for the mapping of the entity is inherited from ClassMap of the fluent NHibernate. These classes contains the mapping for all the properties of the entity class in its constructor. It also defines the database table that the entity maps to.



The class for the mapping of the component (unlike entity the component does not have unique identity in the database, they are associated to the entity for its persistence) inherits from the ComponentMap.


Configuration:



The configuration of the fluent NHibernate is done using Fluently namespace. It creates the new configuration object using Configure() which allows the developer to specify the database and mappings configuration to build the NHibernate session factory. The session factory is tightly bound to specific database. The NHibernate can be configured to work with multiple databases by creating different session factory objects.


Let's have a look at the CRUD operations using Nhibernate:


Create/update:



The create and update can be done with NHibernate using its SaveOrUpdate() in the current active session. The code shown above creates the new entity in the database if it does not already exists otherwise it updates the particular entity in the database. This is achieved using the internal map of NHibernate. When the call to SaveOrUpdate() is made the NHibernate checks its internal map to identify the database row for a particular domain entity. It then creates the appropriate SQL statement to achieve desired output.


Read:



The NHibernate uses DetachedCriteria class to generate SQL query. The above example creates the query on the Book entity and filters the results based on Title and Author. The DetachedCriteria should be bounded to a NHibernate session object before it is executed. The execution of the SQL query happens with the call of List().


The test cases for the above code is as follows:



The test cases are self explanatory. If you are new to the unit testing then please refer to my post at: http://pratikrpatel.blogspot.com/2011/03/unit-testing-stay-focused-on-your-code.html


The process of writing mapping files is quite cumbersome for the developers because it follows the XML standards with is very different from the application programming standards. The fluent NHibernate assembly is a wrapper façade (ref: http://en.wikipedia.org/wiki/Facade_pattern) that generates the mapping files automatically based on the C# code. It eases the load of the developer to create xml files manually.


The process of generating database schema based on the domain model goes hand-in-hand with the application domain model. The Nhibernate provides tools which can create the database schema automatically based on the mappings. The SchemaExport class located under NHibernate.Tool.hbm2ddl namespace. The sample code for generating DB schema is shown below:



The evolution of ORM tools may greatly reduce the developer's effort of writing database code. It also ensures that the developer can interact with the database seamlessly. The ORM tools include other features like connection management, caching, etc. which enables developer to interact with the database effectively.

Cave Inimicum, Colloportus!

Wednesday, September 28, 2011

Aspect oriented programming (AOP) using Castle Windsor

In this post, I am going to discuss AOP methodology using Castle Windsor. There are always multiple ways to code the given functionality. It is advisable that the coder should always analyze pros and cons of each technique before implementing the code. The technique with less number of disadvantages yields good code which is easy to maintain and extend over a period of time. The good quality software should satisfy both the functional implicit / non-functional requirements and should be understood better by any developer.

Typically a software is made up of blocks which are often known as components analogous to the book made up of pages. Generally components are seen as a functionality or the subset of it.Components can also work as the helpers to the other components that abstracts away the common tasks from the main components and makes the code more reusable. The software can have many different horizontal services (common components) which are often implemented separately from the main components. The components that can be treated as a horizontal services could be logging, exception handling, authentication, basic pre-conditions, etc. These components can be implemented separately in all the functions but the code may become cumbersome to maintain. On other hand, we can define common code which handles these functionalities outside the method body and hence keeps the code cleaner and more readable.This technique is known as aspect oriented programming (AOP). Let’s evaluate both the technique individually.

Horizontal services as a part of main components: This is the conventional and traditional way of implementing supporting functionalities. The common functionalities is mingled with the main components in this approach. Consider the following example for authentication and logging functionality:

Consider that the code mentioned above is common for all the function across the whole product.In such cases, the number of lines of code increases if it is repeated in all the functions.Additionally, the changes in the logic needs to be reflected in all the functions. Supposing the average product has around 300 different types of functions then it becomes very difficult for a developer to manually change all these functions to reflect common functionality everywhere. It also becomes difficullt for a programmer to establish common code for these functionalities because all these functions may have different signatures and number of parameters.

Obviously to get rid of such nightmares we need a framework which provides efficient, convenient and uniform way of reusing the code. This is where AOP pitches in. The AOP is implemented using interceptors to the functions. The interceptors are functions that gets executed when the main function is invoked. The interceptors defined in the type are registeredagainst the types used in the product e.g. domain entity or repositories. Lets discuss aspect oriented programing using Castle Windsor.

Aspect oriented programming with Castle Windsor: The Castle Windsor is open source project that provides framework to implement AOP methodology. Lets have a look at the code below:

Code snippet - 1

Code snippet - 2

The snippet-1 defines the logging aspect which can be applied to all the functions across the product. The class implements Iinterceptor interface which is located in Castle.DynamicProxy namespace. The interface has Intercept() which gets executed everytime the function is invoked from its registered type. The interceptors are registered for a particular type as shown in snippet-2. The tangible advantage of using this methodology is to get rid of writing the code for logging across all the functions. Instead, each function call gets intercepted by a separate class and the code gets executed for all the functions. The call is redirected to original function using Proceed(). The arguments to the function is encapsulated in the reference of Iinvocation interface which is passed as a parameter to Intercept(). The Castle Windsor also provides the standard implementation of IInterceptor interface in the framework class called StandardInterceptor. This class provides following three methods:

  • PreProceed : Gets executed before any function gets executed. This can be used to assert the pre-conditions for the function.
  • PerformProceed : Includes the call to the actual function.
  • PostProceed() : Gets executed after any function gets executed. This can be used to log the function output for diagnosis purpose.


There can be multiple interceptors registered for a type. The code for registering multiple interceptors is as follows:

Aspect oriented programming is a methodology that helps the programmer to write a clean and modular code. There are many terminologies associated to AOP which is out of the scope of this post. You can find more details related to aspect oriented programming with Castle Windsor at http://docs.castleproject.org/(S(mbos0245qatumh55n2vcpjag))/Windsor.Introduction-to-AOP-With-Castle.ashx

The greater separation of concerns, the cleaner source code!

Tuesday, April 26, 2011

ASP.NET MVC 3 and jQuery – Two cookies for a <geek>

The evolution of the technology has always been on the radar for all the technocrats working in any technology vertical. The techies working on windows/.NET platform are no exceptions to it. The .NET framework supports the development of websites right from its inception. Today the ASP.NET has completely replaced ASP 3.0 with its numerous new features that easily facilitated the increase in the performance and responsiveness of the websites.

With the increase in popularity of the web, it became a challenge for many organizations to direct and nourish its technical talent towards web development who were writing win32 application previously. The developers and architects started writing business applications using ASP.NET webforms. The concept of code-behind and .aspx page followed the principle of separation of concerns by isolating the C# code from the HTML/server scripplets. This helped the HTML designers and C# coders to write their code simultaneously without being dependent on each other. This paradigm was widely accepted with the compromise on the code reusability. It wasn’t very easy to reuse the page or the part of the page with ASP.NET webform application.

ASP.NET MVC framework, being very close to ASP.NET, gives the cleaner and better separation of the UI (View), the event wiring/UI rendering code (Controller) and the data (Model). This framework gives the ability of reusing the UI (partial views) to a greater extent without worrying about duplicating the server-side code. The view can be visualized as the page or the user controls that is modified/updated independent of other controls on the same page.

View and partial views: The view/partial view is the user interface screen that is operated by the user of an application. Views are generally written using HtmlHelpers which are often understood as a wrapper over the intrinsic HTML/Server controls. The view usually contains HTML code, javascript/jquery code or quite a few partial views that shows different set of information from the rest of the view. The partial views usually have different controllers and model data. The sample view code looks as below:

Razor view (ASP.NET MVC 3): Razors are the new view engine that is available as a part of MVC v3 framework. It gives the easy and consistent way to write code. The scripplets (<% %>) are replaced by @. It reduces the keyboard strokes for a developer to focus more on its logic and functionality. The sample razor is shown below:

Controller: The controllers are the means of communication between views and application data. It captures the event raised by the user actions on the view and takes proper actions. It also helps the view to display data that are often referred to as an application domain model. The controller is a plain C# class which is inherited from Controller base class. It contains methods known as “Actions”. By default, the name of the view is same as the name of the action method. E.g.: The action method Create will render the view named Create, by default. Based on the type of HTTP method (verbs) the action method can be of two types: Get and Post. The Get action method gets executed when the user request particular URL and the view gets rendered. The Post method gets executed when user submits the form with the Submit button. The form data is encapsulated in FormCollection class and passed as the parameter to the respective Post method. The sample code is shown below:

Model: These are plain C# classes that represents the database entities. It is the actual data that are fetched by the controllers and/or repository layer from the database and shown on the view using ViewModels. ViewData is the ASP.NET MVC intrinsic object that facilitates the data communication between controller and view. Apart from this, ViewData can also acts as dictionary object that allows controller to add the custom data with the unique key.

Exception handling: ASP.NET MVC gives a mechanism to identify whether or not the model is in the valid state before operating on it. The AddModelError() adds the model specific error to the model and sets the state of the model (ModelState) to invalid.

The ASP.NET MVC framework does not have any limitations as compared to conventional ASP.NET webforms. It does not replace ASP.NET webforms. This essentially means that all the intrinsic controls and objects that are available in ASP.NET are also available in ASP.NET MVC framework. MVC comes with the advantage of flexibility and decent coding style. ASP.NET MVC partial views, if programmed as a widgets/web part, can be reused across multiple views/partial views analogous to gadgets in iGoogle! E.g.: The view for search can be reused for searching multiple domain entities in your system viz. it can be used to search the employees as well as the contacts without any major changes. The concept of the views gives a cleaner separation from the rest of the code so that the views can be changed/plugged in easily. There are other numerous articles on internet that gives a good insight of the ASP.NET MVC framework. It is a developer and product stakeholder's choice as to what framework to use for their web development.

jQuery – the open source javascript framework – has gained lot of popularity recently for developing large scale web products with very rich user interface. The jQuery gives the wide set of API’s to the UI developer to program against individual HTML elements. E.g.: With the power of jQuery the UI developer can manipulate table rows very easily (certainly “write less, do more”). Being an open source community framework there are lots of improvements happening on it to make it better and more robust. jQuery follows the javascript coding style. The sample jQuery code is shown as below:

[The code binds the click event on input element with the ID=’cmdSearch’ as soon as the view is rendered. The Search() gets the value of input element with the ID=’txtSearch’ and makes the ajax call].

The $(document).ready() [jQuery(document).ready()] event gets executed with the page’s body is loaded on the browser. jQuery is often abbrevated as $ symbol. Like .NET controls, jQuery also works on selectors (handle) of the UI elements. In above figure, two event handlers are wired to their respective UI elements in $(document).ready(). The developer may like to include the reference of jquery-1.5.1-vsdoc.js file on the view to get jQuery intellisense in the VS.NET IDE. Notice the usage of jQuery ajax api ($.ajax) that executes the action on the controller and fetches the data. Here, the searchFilter is passed to the HomeController’s Search() which is decorated with Post verb. The success callback function gets executed upon successful return from the controller’s action method. The callback function renders the view as the html to refresh the UI after returning search results. jQuery framework is the real-world example of lot of code.

</geek>

Sunday, April 17, 2011

नमस्ते
Accompanied by the typical Sunday laziness, I came out of my place to have a casual walk looking at the few tea stalls and pani puri centres which were lightened up with the emergency lanterns. My eyes were looking at few people who were sharing news about the new happenings in their life and few of them waiting for their family members to join them in a park. Few shops doing business like they usually do. Folks, generally, address such phase of life as stagnant and the routine. Taking a step further on the pavement I just realized the importance of having community friends all across the globe who does the stuffs similar to what we do but in a different fashion, in a different way. The way they interact, the way they present and the way they accomplish it’s all different! These differences are obvious due to diversity in their culture. Due to this there was a need to establish a lingua franca to ease the communication amongst the people who belongs to different places! The language could be the plain English language or C#.NET! Yes really :)
The need and craving of the people to know each other all across the globe gave the rise to community websites. I remember the time when orkut gained its popularity amongst the net surfers because they could find their friends whom they have not met since a very long period. They can join the community which they were already part of in their past. They can see what their friends are doing now-a-days. They can see the pictures of their recent birthday party and everything else which a friend may want to share. All these information became very handy and could be reached at a mouse click!
The community website has also become a means of business development for some industry. It’s really a no surprise if the marketing team spends their entire life on facebook, orkut, myspace, twitter, linkedin and other community websites. It became very easy and economical for the companies to setup their team to do the market research and analyze the market trends using these websites. These website also provides a range of software applications that automates the analysis and brings up the information to its users or the business partners. The real world example could be a simple website showing the number of users visited it till date. The marketing team may want to show the region specific advertisements based on the location of the user currently logged in the website. It can also be parameterized by the interest of the user, his age, his profession, his wishlist, etc. The list may go endless.
Technology industry, being a very close to internet, have made the most out of these websites. Isn’t it fascinating to send the message to millions of users about your new product release within a second? It is more effective than printing the pamphlets and circulating across all the shops, shopping malls, theatres, traffic signals, etc. Really amazing and quick!
Codes & Notes is neither of the above. It is not as great as MSDN or any other open source project hosting website. It is just a mirror of an average mind who aspires to explore all the horizons. The technical concepts to put here might be limited but the thoughts are unlimited. It surpasses any machine or a robot that are pre-programmed, in a sense; they know what to do next and how to do it. It is probably that they cannot innovate or cannot learn from their experiences and convey it effectively to make a better tomorrow. This is probably the only reason why humans are said to be “grownup” whereas others are “built”. Respecting this attribute of the humans, I promise to bring up the new solutions on the table and eventually on a whiteboard to satisfy the craving to learn something. There is literally no full stop to this space and hope it grows very rapidly.
That’s all for now we'll be right back at the same location and same space. Till then have a great time. Adiós
જય શ્રી ક્રિશ્ના

Saturday, April 16, 2011

I18n and L10n of the .NET application

Today I was very happy to see the orange sunset once again after a very long time. It is a scientific fact that the color of the visible light spectrum which is reflected the most is the one that is seen most prominently through the transparent surface. The sun never changes its appearance but it is the light travelling from it and reaching our eyes through the atmospheric particles during the entire daytime makes it to appear in different colors at the different times. This is the most common example where the external appearance of the entity is dependent on the external factors. This is quite analogous to the process of developing and deploying the large scale multi-lingual applications in the production environment. In such scenarios the content to be displayed is isolated from the executable code.

Internationalization is the process of designing a software application so that it can be adapted to various languages and regions without engineering changes. Localization is the process of adapting internationalized software for a specific region or language by adding specific components and translating text (ref: Wikipedia)

The products which are targeted for the users all across the globe may need to be designed in a way they can be used by the target audiences from different geographical locations. This may bring up different challenges for a developer and a content writer working on the multilingual applications. For a developer he may need to make his code generic enough so as to fit the text data written in the different languages. For a content writer it is probably the text encoding and other parameters that matters the most. From the developers perspective the well externalized application is the master key to achieve the internationalization of any product. Let’s have a look at .NET-way of doing it.

The .NET application can be divided into two parts:

1) Executable code: The code which gets compiled in the form of binaries.

2) Content: The literal or static text which is separated into different unit of deployment which is often known as satellite assemblies. The satellite assemblies are often deployed separately and independently from the product feature release.

Project structure:

1) Code files: This chiefly consists of C# code files which compiles in the form of binaries

2) Resource files: This contains the content to be rendered based on the culture set by the user. The naming convention should be followed precisely so as to load it for a particular culture e.g. the content written in US English should contain en-US in the name of its resource file. The satellite assemblies that are created after the successful build are placed inside the respective folders with the same name.

The hub and spoke model of deployment

While writing such kind of applications it becomes mandatory for a developer/content writer to identify all the user interface texts which needs to be externalized. Essentially it means that the developer cannot hardcode the literal string value anywhere inside the code but instead he needs a placeholder to refer all those values from outside the executable code. The code sample is illustrated as below and very simple to understand.

System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-GB");
ResourceManager resourceManager = new ResourceManager("Core.Content", Assembly.GetExecutingAssembly());
var userName = resourceManager.GetString("UserName");

The above code can be made to work for all the available cultures by setting the CultureInfo from the http request or taking it from the regional settings for the current user and creating the resource files for each of them. The satellite assemblies can also be created separately and copied to the \bin folder of the application so that it is picked by the application upon the next user request.

This is the another example of the beauty of the .NET framework which abstracts all the internal implementation from the developer and gives a nice and wide range of framework classes to work with the multi-lingual applications.

Find what varies and encapsulate it!

Tuesday, April 12, 2011

Programming with Entity Framework using DDD and
LINQ/Lambda expressions using LINQPad 4

I always like to keep my mind busy with quite a few small software tasks while watching a movie or IPL cricket match and having a sip from a glass full of hot almond chocolate milk. Last week I had got the chance to see the T20 match between Pune Warriors India and Kings XI Punjab while thinking about LINQ and Lambda expression in C#. I completed the coding and subsequent write up faster before completing my chocolate milk analogous to how cricketers compete in T20 matches. The write up is based on the extension of the methodology of developing N-tier database applications which follows Domain Driven Design approach a.k.a. DDD. Though this approach does not replace the conventional methodology of writing database applications wherein the design generally starts with database table design and goes up till the user interface but it gives a more obvious way of realizing the model entities and their associations in the applications from the application perspective.

Domain model is the heart of DDD. Model defines the domain entities and their associations which constitutes the application and eventually defines the structure of the database/data store which is more or less same as the application class diagram. This mapping is known as ORM (Object-Relational mapping). It can be understood as follows:

C#
Database
Class
Table, Procedure, View
Field/Property
Column
Property of associated class a.k.a. Navigation propeties
Tables linked with the referential integrity – foreign keys

The use of ORM also reduces the developer’s burden of writing stored procedures for operating on the database. The tools that are most commonly used for ORM are NHibernate (available from the open source community) and Entity Framework (VS.NET). The ORM and LINQ (Language Integrated Query) serves as a basic framework for achieving the CRUD operations in any application. It is often experienced that an application may fail or tend to fail when its domain model is not prepared as it exists in a real time scenario. There may be the case when an architect and a developer together have to spend extra efforts at the later stage of application development life-cycle to stabilize the application as a whole. There are many articles available on internet which explains DDD in greater details. Lets keep it short and simple for the scope of this write up. A typical application which follows DDD pattern has following layers in it:

Finders and repositories:

These are the set of classes which are specific to each entity in the application that executes the search for an entity. It contains as many functions as possible which can able to search entities in all the possible ways with all the possible parameters. E.g. A ProductFinder class can have the functions like GetProductByID() and GetProductByName() to fetch the products based on ID and Name respectively.

Services:

These are the set of classes which helps to expose the functionality to different client application. It should not be confused with a WCF service or a web service which has several endpoints. Instead, the service, in this context is a wrapper for all the DML operations of the application. This can be visualized as the application layer which resides on the top of the repositories and finders. Lets take the reference of the domain model as below and have a brief look at the EF.



How to read the above diagram:

There are 5 entities in the application called CustomerDemographic, Customer, Order, Shipper and Order_Detail. All the entities have their respective tables in the database with each of the field/property mapped to its respective column. The referential constraint for the associations can be understood as follows:

Customer -> Order:
One customer can have many orders.
One order may or may not be associated to a customer

Order -> Order_Detail:
One order can have many order details.
One order detail can be associated to only one order

CustomerDemographic -> Customer:
One customer can have many customer demographics associated
One customer demographic can be associated with many customers

Navigation properties:

The navigation properties aka association path sets the relationship between the entities. The association path can be the property inside a C# class which is of the same type as the associated class. The association can be one-to-one (property of the type class) or one-to-many (property of the type List). The navigation properties can also be visualized as the referential integrity used to create table joins in the SQL.

Programming CRUD operations with EF:

a) Create:
private void CreateProduct()
{
var product = new Product();
// Set the properties and associated entities related to this product entity
product.ProductName = "Product 1";
// The associated entities could be a new instance or the existing ones which are fetched separately from the database
product.Category = new Category() {CategoryName = "Category 1", Description = "Test Category"};
product.Supplier = new Supplier() {Address = "Address 1", City = "City 1", CompanyName = "Company 1"};
// Save to the database and commit the changes
northwindEntities.AddToProducts(product);
northwindEntities.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
}

b) Read
private List<string> GetSpecificContacts()
{
// Get the ContactName of all the Customer whose Order is Shipped by "Speedy Express"
var customerNames = (from shipper in northwindEntities.Shippers
from orders in shipper.Orders
join customer in northwindEntities.Customers on orders.Customer equals customer
where shipper.CompanyName == "Speedy Express"
select customer.ContactName).Distinct().ToList();
// Lambda expressions
var customerNamesFromLambda = northwindEntities.Shippers
.SelectMany(
shipper => northwindEntities.Orders,
(shipper, orders) =>
new
{
shipper = shipper,
orders = orders })
.Join(
northwindEntities.Customers,
temp0 => temp0.orders.Customer,
customer => customer,
(temp0, customer) =>
new
{
temp0 = temp0,
customer = customer })
.Where(temp1 => (temp1.temp0.shipper.CompanyName == "Speedy Express"))
.Select(temp1 => temp1.customer.ContactName)
.Distinct();

return customerNames;
}

c) Update:
private bool UpdateProductByName()
{
var product = northwindEntities.Products.Where(a => a.ProductName == "Product 1").FirstOrDefault();
product.ProductName = "Product 1 Updated";
northwindEntities.SaveChanges();
return true;
}

d) Delete:
private bool DeleteProduct()
{
var product = northwindEntities.Products.Where(a => a.ProductName == "Product 1 Updated").FirstOrDefault();
northwindEntities.Products.DeleteObject(product);
return northwindEntities.SaveChanges() > 0;
}

LINQ – No more round-trips to database:

LINQ is the language feature with which the developer can query the collection analogous to the database queries. This feature came into existence with the increasing demand of performing database look-a-like operations on the in-memory cached data.

Using LINQPad;

LINQPad is the free tool which helps the C# developer to write and test LINQ queries. It helps the developer to convert LINQ to Lambda expressions and Lambda expressions to LINQ queries. It also helps a developer to see the SQL statement that equivalents the LINQ/Lambda expressions. There are other features which may seem irrelevant for a developer while working on line-of-business applications. The screenshot of LINQPad at work is shown below:


Figure 1


Figure 2

Enjoy what you do, do what you enjoy!
Stay tuned, stay connected!