Monday, March 28, 2016

Where my block has been used on server? A question that all back-end developer have in mind



The story started when I had a task to remove old blocks that we don't use any more. From a back-ender's point of view, I just needed to find all references in my code and make sure that it has not been used anywhere. But of course it is not correct when dealing with a CMS like EpiServer since they can be used in a ContentArea.

Yes, I know, we have also [AllowedType] attribute that we use in order to limit contentAreas, but still, there can be some items in blocks tree that has not been used in any page and may cause a problem if an editor click on them.

So what shall we do?

First, Every content in EpiServer will be saved in tblContent. if you want to make sure that there is no instance from your typename it is enough to check that table.Code:
SELECT c.*   FROM [dbo].[tblContent] c
inner join [dbo].[tblContentType] ct on c.fkContentTypeID = ct.pkID
where  [ModelType] like '%TypeName%'

But it is only 10% of the cases, besides where is the fun?!!!
I want to know how many instances of my type exists and where are they now? also I want to know how to find their parent in the tree. So I wrote this code:

Code:
declare @TypeName nvarchar(50)
set @TypeName = 'myBlockType'

select tbl2.contentName as contentName, tbl2.contentSegment as ContentSegment, tbl2.ContentGUID as ContentGUID,
con2pkID ContainerID,con2ContentGUID ContainerGUID, conLang.name as ContainerName,conLang.URLSegment as ContainerURLSegment, contype.Name as ContainerTypeName, 
contype.ModelType as ContainerModelType, con2.fkParentID as ContainersParentId, conContainerParentLanguage.Name as ContainerParentName, conContainerParentType.Name as ContainerParentName

from [dbo].[tblContentProperty] cp  
 inner join 
(SELECT  c.*, cl.name as contentName,  cl.URLSegment as contentSegment FROM [dbo].[tblContent] c
inner join [dbo].[tblContentType] ct on c.fkContentTypeID = ctpkID
inner join tblContentLanguage cL on cL.fkContentID = c.pkID
where  ct.Name like @TypeName)  tbl2 on cp.LongString like '%'+cast( tbl2.ContentGUID as nvarchar(50))+'%'
inner join tblContent con2 on con2.pkID = cp.fkContentID
inner join [dbo].[tblContentType] contype on con2.fkContentTypeID = contypepkID
inner join tblContentLanguage conLang on conLang.fkContentID = con2pkID
inner join tblContent conContainerParent on conContainerParent.pkID = con2fkParentID
inner join tblContentType conContainerParentType on conContainerParent.fkContentTypeID = conContainerParentTypepkID
inner join tblContentLanguage conContainerParentLanguage on conContainerParentLanguage.fkContentID = con2.fkParentID

This code will show you all instances of a type, and where they have been contained including typename and the address that we can find the parent in the tree.


The result will be something like this



But wait a minute! what if I can't find the container it self?!
Well, that is easy :)  the query is 90% the same, but we just need to search for the contentId (instance) instead of the type name.
Of course if you search for the containers type name, you will eventually find it, But it is easier to change 2 lines of code :)

Code:
declare @ContentGUID nvarchar(50)
set @ContentGUID = 'B6845FFC-5475-4FC3-C701-5A5D6FD5F967' -- put you content GUID in here 

select tbl2.contentName as contentName, tbl2.contentSegment as ContentSegment, tbl2.ContentGUID as ContentGUID,
con2pkID ContainerID,con2ContentGUID ContainerGUID, conLang.name as ContainerName,conLang.URLSegment as ContainerURLSegment, contype.Name as ContainerTypeName, 
contype.ModelType as ContainerModelType, con2.fkParentID as ContainersParentId, conContainerParentLanguage.Name as ContainerParentName, conContainerParentType.Name as ContainerParentName

from [dbo].[tblContentProperty] cp
 inner join
(SELECT  c.*, cl.name as contentName,  cl.URLSegment as contentSegment
FROM [dbo].[tblContent] c
inner join tblContentLanguage cL on cL.fkContentID = c.pkID
where c.ContentGUID like @ContentGUID)  tbl2 on cp.LongString like '%'+cast( tbl2.ContentGUID as nvarchar(50))+'%'
inner join tblContent con2 on con2.pkID = cp.fkContentID
inner join [dbo].[tblContentType] contype on con2.fkContentTypeID = contypepkID
inner join tblContentLanguage conLang on conLang.fkContentID = con2pkID
inner join tblContent conContainerParent on conContainerParent.pkID = con2fkParentID
inner join tblContentType conContainerParentType on conContainerParent.fkContentTypeID = conContainerParentTypepkID
inner join tblContentLanguage conContainerParentLanguage on conContainerParentLanguage.fkContentID = con2.fkParentID

Monday, March 21, 2016

Agile Software Development: Are we really equal?



When people talk about agile process like Scrum, it is pretty normal to hear that there is no job title like architect or programmer, etc. so many will think that as a "developer" or a"team member" everyone has to be equal. Well :) if you think the same, you are wrong.

Agile process' usually define for a small teams (like 4-9 team members) so it is understandable to expect people to have some common knowledge, but of course that doesn't mean that you are equal even if the whole team works in a same department. 

Here I want to share some of my personal experiences with you:

Personal Experiences


It is very important to recognize the individual in the team. Each person has some special abilities and came from different background, We all write software systems but even on a single project, we have different tasks so it is clear that each one looks at the task from different aspect.
When team needs to take a decision about an issue, it is important that all attend the meeting and share their ideas, but it is predictable that someone who has some background will have more to discuss. More importantly it doesn't mean that you have to convince everyone that the idea is great. Of course if your team members are mature enough, they won't insist much to choose the easy way when the ones with more experience already chosen another one or vise versa.

As an example, I was working in a very good team and all members were senior developers and we used scrum. When there was a discussion about structure or architecture, it was people with architecture background who discussed the ideas mostly, but of course everyone shared their ideas and tries their best to improve the solution. After some discussions, sometimes one or 2 didn't convince totally but since we know each other, we just trust on the solution on experts.


The role of a "dean"


On a daily basis, a normal team can handle most situations. But there are some times that you need to ask someone to help you choose. I want to emphasis on that there is no boss or things like that in the team and when I refer to dean I don't mean someone that is superior to others in any aspect, I specially believe that a software team has to be flat and everyone has to be responsible for what he do. So what does it mean to have a dean?!
A dean is someone whom you trust, with his judgment. It doesn't even mean that the one has more knowledge than you.
For instance, we had a small project and we had to implement a service with lots of needs. The 3 of us researched for 2 weeks and discussed the solution almost everyday. After all, we could't agree on a single result since there was different possible scenarios. Then we explained everything to the one and asked him to choose between our solution.


Bug Ratio and "Blame" tools


It is really important to know that we don't blame people for their code! Because we all know that as humans we all make mistakes and more importantly as a team we have to support each other, not to blame each other, So how can we use the blame tool? (as git called)
Believe it or not, we know each other when we work together for a portion of time and we use this knowledge to understand why someone did something. To be more specific what is your reaction when you have to change an old code and you think it is not efficient, or it is not what you think it has to be?

* If you simply change it to what you think is correct, or you afraid of changing it at all then you need to gain more experience, please don't change anything and ask someone with more experience to work in pair with you for some time.

I normally try to understand the method, what it does, why the one implemented it like that and where it has been used, If I still believe that it is not good and I want to change it, I will check the history line by line using blame tool to understand the process of change and to define the owner. If the code has been changed dramatically by time, or if the owner is someone with normal bug rate, I will refactor the code immediately. But if the code has been written by someone who has low bug rate, (someone who maybe has a clue about the future) I will talk to him first, because it is probable that he knows something that I missed.



Tuesday, March 15, 2016

EpiServer for beginners: How to add custom fields to Order (eCommerce)

Introduction

One of the simplest things that any developer would want is to add some fields to Order table or in related ones. When dealing with content pages, it would be handled automatically using Code-First methodology. But in the eCommerce system you have to do some steps.

Example

When you are dealing with external systems, you will need to have their Id in your system and since it is related to your order, well it is not a good idea to put in somewhere else.
Also, you may want to add external fields like status or etc to your order.

Steps

steps in Ecommerce

1- Go to Commerce Manager> Administration >Meta fields> New Meta Field



2- Fill name and friendly name and choose type of your field. Then choose properties like search option as you need. just have in mind that changing allow null field would be hard.

In these 2 steps, you've created a field in your order. Now you have to assign it to any table that you need.
3-  Go to meta classes right under order systems and select the main table(element) that you want to add your field. For instance, I want to add my field to my order form.

4- Now select the related external table related to that element. For order from it is only one, but it differs from element to element.
5- Select your field and click "OK"

Steps in your code

We have our field in our DB now.It is very easy to use it in your code.
The easiest way is to write a code like this line for setting the field:

Code:
 order.OrderForms[0]["MyFieldsName"] = value;

And Like this one to Getting it (for strings):

Code:
var x=order.OrderForms[0]["MyFieldsName"].ToString();

But It is always good to have a class, that contains names and methods for handling fields and their names.
Use Constants to avoid writing wrong names. Also set and get all fields in the same class so you have them centralized and use those methods.

Code:
 private const string MyFieldName = "MyFieldName";

public static string GetMyField()
{
   return order.OrderForms[0][MyFieldName].ToString();        
}

Edit:

I wrote a post in here  describing how to add the field grammatically.

Tuesday, March 8, 2016

A simple queue for EpiServer

Intro
Queuing is one of the base procedures that you may need as a software developer specially if you are working on web.Think as a task that you want to make sure that it will be done, but you don’t want to suspend your current process for it. for instance you want to send an email in a part of a method or task. you don’t want to wait for email response and you want to try sending it for many times, but you never want your methods to wait for it.
If you are developing on EpiServer, you probably know that there is a dynamic data type which is pretty good for implementing a queue.

Cecilia von Wachenfeldt has a post in here where she describes a simple solution for that. However, I don't like to have both queue and queue item on the same class. From the software architectural view, we have to have a queue class that handles primitive queuing functions (adding to queue, finding unprocessed items, Processing items and deleting them). Then for each type queue, we can just create a corresponding queue-able Item and ask use our queue to handle the object :)

Theory

There has to be a queue, with queue functions. There has to be an enum for the status of the item. Then the queue has to handle everything using each items methods.

This is the list of classes that we need:

1- Queue
2- An interface for Queueable Items (IQueueable)
This interface contains properties that the queue will use like ErrorCount, LastError, Status, etc. and basic methods for processing each special type Like Process().
3- Queueable item which inherits from our IQueueable
This item is simply the object that we want to save into DB. It contains our queue properties/methods and also the required data that you need to use, in order to proceed.

Implementation
Lets say that we want to implement an email queue system, so if the network was down or etc, we won't loose any emails. Our queue and IQueueable are of course the same but for the Queueble Item we have something like this:
First, we have to implement our enum to decide if the item is
Code:
public enum QueueItemState
{
Queued = 0,
Processed = 1,
Retrying = 2,
Failed = 3
}
Then we have to write our Interface:
public interface IQueueableItem
{
int ErrorCount { get; set; }
string LastError { get; set; }
DateTime? QueuedTime { get; set; }
DateTime? CompeletedTime { get; set; }
EnumsQueueItemState State { get; set; }
void AddError(string errorMessage);
bool Process();
Identity Save();
void SetToFaild(string errorMessage);
}

Then we have to implement our interface and add our additional functionality/properties:
(Pay attention to EPiServerDataStore property that cause Episerver to save this item into DynamicData )
Code:
[EPiServerDataStore(AutomaticallyRemapStore = true, AutomaticallyCreateStore = true)]
public class QueueableEmailItem : IDynamicData, IQueueableItem
{
.... [IQueueableItem properties]
public string EmailSubject { get; set; }
public string EmailBody { get; set; }
public string EmailTo { get; set; }
public int? EMailPriority { get; set; }
public bool Process()
{
var priority = EMailPriority.HasValue ? (MailPriority)EMailPriority.Value : System.Net.Mail.MailPriority.Normal;
MailService.Service.Send(EmailSubject, EmailBody, EmailTo, priority, attachedItems);
return true;
}
}

We will need a QueueBase class that handles your queue items. The queue will try to read and execute data that implement IQueueableItem. 
There is only one problem, which is reading items from DB with generics, So I just do the process in the queue base and do the other stuff in the inherited classes using polymorphism.
Code:
public abstract class QueueBase where T : IDynamicData, IQueueableItem
{
public void Proceed()
{
var queue = GetQueuedItems();
if (!queue.Any())
return ;
foreach (var item in queue)
{
try
{
// Exit if the error count is greater or equal to the retry count
if (item.ErrorCount >= RetryCount)
{
item.SetToFaild("RetryCount limit");
continue;
}
if (item.TryProcess())
{
item.State = Enums.QueueItemState.Processed;
item.Save();
continue;
}
item.State = Enums.QueueItemState.Retrying;
item.Save();
}
catch (Exception ex)
{
if (item.State!= Enums.QueueItemState.Failed)
{
item.State = Enums.QueueItemState.Retrying;
}
item.AddError(ex.message);
item.Save();
}
}
}
}
Of course you can have a better code, add logs/ return report/ send email to admin if failed, etc. but this is the simplest code that I could come up with :)
Now we will need to inherit from this class for the emailQueue:
Code:
public class EmailQueue : QueueBase<QueueableEmailItem>
{
public Identity AddToQueue(string to, string emailSubject, string body, MailPriority mailPriority = MailPriority.Normal)
{
var item = new QueueableEmailItem
{
EmailTo = to,
EmailSubject = emailSubject,
QueuedTime = DateTime.Now,
State = Enums.QueueItemState.Queued,
ErrorList = new List<string>(),
EmailBody = body,
EMailPriority = (int)mailPriority
};
return item.Save();
}
protected override List<QueueableEmailItem> GetQueuedItems()
{
var store = typeof(QueueableEmailItem).GetStore();
var query = (
from item in store.Items<QueueableEmailItem>()
where item.State == Enums.QueueItemState.Queued || item.State == Enums.QueueItemState.Retrying
select item);
return query.ToList();
}
}

Fake Entire EpiServer

Intro
When doing the integration testing in EpiServer, you will need to mock more than one or two methods or services. Sometimes you need to implement the same ground for different test classes. but it will be very time consuming and at the same time, very hard to write.
Take a simple collaboration service as an example. Your service probably used 3-4 different EpiServer services and 3-4 of your other services (at least:) ), but when you want to test them you find out that you have to mock all used services for your class/service.

An alternative to this option will be to fake all APIs that you've used from EpiServer and then load the faked content on the initial step of your test classes.

Well, it is like having a huge castle floating in the air. :) time consumable to implement but really easy to expand and change.

FakeMaker
So I have an advice for you if you want to fake EpiServer content. Use the FakeMaker by David Vujic to create your pages which will add them automatically to your repository and serviceLocator.
You can more data about it here or download it from github or even nuget.

Need to mention 2 things:
1- Don't do create a new serviceLocator. Create your pages with FakeMaker and then get your ServiceLocator mock object using this command:
Code:
 var mockLocator = Mock.Get<IServiceLocator>(ServiceLocator.Current);
You will have access to the content repository with your FakeMaker.ContentRepository easily.

2- If you have EpiServer 8 you cannot use the nuget. just download his code from github and use it. It is very well written and easy to use

My Extention
When I saw FakeMaker, I understand that it can be pretty usable for many people including me :)  so I had a discussion with David and he liked my Ideas. Then I realized that I can contribute in the project so I add other features to my branch. It is not that big deal, but it can be useful for many.
I've add 2 options:
1-Supporting EntryContentBase for Commerce system
You can now easily add your products to your fake. It is as easy as creating FakePages. For instance:
Code:
 var shopRoot = FakePage.Create("ShopRoot");
 var fakePhone = FakeEntryContent.Create<PhoneProduct>("Iphone 6").ChildOf(shopRoot);
_fake.AddToRepository(shopRoot);

2-Supporting ContentLoader
In our code, we used ContentLoader in many places while we also used ContentRepository. Of course I wanted to support the ContentLoader when I call AddToRepository :)
You can have access to ContentLoader the same as ContentRepository by FakeMaker.ContentLoader.
Just to mention, it make more sense to create your content in FakeMaker first and then use ContentLoader, ContentRepository, and serviceLocator that it creates for you.


*You can find my code in here. Just to mention, it is not confirmed by David yet, so it is only on EpiServer 8 that I am using right now and it is not available through nuget pakages, yet.


Unit Testing in EpiServer using Moq

Regardless of what do you think about TDD (Test Driven Development)  there are many scenarios that you want to implement an automatic testing in your code. But how do we implement tests in a CMS like EpiServer?
As a basic step, one has to mock some behaviors in EpiServer services like ContentRepository, ContentProviderManager, etrc. To do so, you have to create a mock object from that interface and then use that mock instead of real object. For instance we can do these steps using Moq library:

1- Create a mock for the service that you want to use
for instance you can create a mock for content loader. This class has been used to load contents from EpiServer, like when you want to load and use a specific page (like setting page) or content.
Code:
var mockContentLoader = new Mock<IContentLoader>();
 2- Mock methods that you need
now you have to tell Moq what you want to return instead of the normal behavior.

We can ask for a general behavior like returning an object if there was a request for a type. like
Code:
mockContentLoader.Setup(r => r.Get<StartPage>(It.IsAny<ContentReference>())).Returns(new StartPage());
this code will return a new StartPage when someone uses ContetnLoader.Get<StartPage> method, with any ContentReference.
    Or we can mock an specific request like
    Code:
    mockContentLoader.Setup(r => r.Get<StartPage>(myStartPage.ContentLink)).Returns(myStartPage);
    This code will return your startpage if there is a request with it's content link. Pretty similar to how you code on EpiServer :)
    3-Use the mocked class
    To use the class that you mocked, you need an object from it. For instance, when you want to test a class that need your ContentLoader you can do it like this:
    Code:
    var myServiceToTest = new MyService(mockContentLoader.Object);
    Now you can use your class/service and whenever it wants to use the content loader, it will have the mocked results instead of trying to call DB or etc. :)

    *If you want to use the injection in your code, you have to  create a new mock for ServiceLocator, or get it if you already have it.
    To create a new one use this:
    Code:
                var mockLocator = new Mock<IServiceLocator>();
    To get the existing one use
    Code:
    var mockLocator = Mock.Get<IServiceLocator>(ServiceLocator.Current);
    Now you can easily use the same concept and return your mocked class easily
    Code:
    mockLocator.Setup(l => l.GetInstance<IContentLoader>()).Returns(mockContentLoader.Object);
    You just need to remember to set the new serviceLocator
    Code:
    ServiceLocator.SetLocator(serviceLocator.Object);
     To read more about Moq go to this page