Hosk’s Top CRM Articles of the week – 24th July

Article of the Week

Asynchronous Batch Process Solution Revisited – part 1

Asynchronous Batch Process Pattern: Part 3

I enjoyed reading these two articles

Best of the Rest

CRM 2015 – Understanding impersonation in plugins and knowing when to use it

A look at plugins and understanding impersonation, when, why and how to use impersonation

Updating and Publishing webresources directly from Visual Studio

A tool to update web resources from Visual studio

MICROSOFT ANNOUNCED ITS CERTIFICATION FOR DYNAMICS CRM ON-PREM RUNNING AZURE IAAS

It’s finally certified

CRM 2013 – Workflow error AccessCheckEx

The Hosk got an error, find out how I worked out the cause and my solution

Querying More than 5000 records in Dynamics CRM

Interesting article talking about paging when selecting lots of records

CRM 2015 – What is the CRM Outlook reading Pane?

The CRM outlook reading pane caused me problems this week

Visual Studio 2015 Shared Projects and CRM Plugins Development

Excellent new functionality in Visual Studio 2015, help you get round the dll/ilmerge problems

CRM 2015 – Understanding CRM Metadata

What is Metadata in CRM 2015

Tracking the Movements of a Case

Leon Tribes shows how a no code solution to tracking the history of a case.

Microsoft Dynamics CRM Mobile SDK Update and Azure Mobile Connector SDK

CRM SDK for Mobile and Azure

CRM 2013 – Understanding SystemJobs and Async Plugins

Understanding System jobs and async plugins

Using Windows Resource Monitor to Find Unusual Performance Bottleneck

Great use of windows resource monitor to diagnose a problem

How to cascade activate / deactivate (SetState) in CRM

Do you know your cascading

Getting the CRM Developer toolkit working with Visual Studio 2013

Tutorial to get CRM Developer toolkit working with visual studio

programming

Announcing the latest improvements for the F12 developer tools in Windows 10

Group Flow in Software Development

7 Tools to help you gather better software requirements

Building your mental toolbox for solving coding problems

Other articles interesting the Hosk

free minding hacking book

awesome mind maps/sketches of books

Why Exercise Won’t Make You Thin

Billy Beane on Making Better Decisions and Avoiding Biases

Mental Model: Regression to the Mean

BBC iPlayer ‘watched by more than 60 million people outside the UK for free’

“How To Pick The Perfect Book Title”

short master course on Thinking about thinking

Previous top picks

Hosk’s Top CRM Articles of the week – 17th July

Useful Hosk Links

Hosk list Of CRM 2013 Tools

A list and review of CRM 2013 tools, this will probably work in CRM 2015 as well

Hosk’s CRM Developer Articles

A collection of my favourite CRM Developer articles I have written

MB2-703 – CRM 2013 Customization and Configuration Certification Information

All the CRM 2013 content to help you pass the exam

HoskWisdom – Hosk Developer Quotes

 Words of Wisdom from the Hosk.  I have written over 900 articles, surely I should have said a few memorable things

CRM 2015 – What is the CRM Outlook reading Pane?

I have started using CRM 2015 SP1 and the navigation tweaks are awesome.  So I will congratulate Microsoft on the navigation tweaks and wonder how they got it so wrong in CRM 2013!

The Outlook reading pane is a pain, that’s not entirely true but for an hour today it caused rampant confusing and gnashing of teeth.
I will explain the problem I had first.
CRM Developer Joe was perplexed because the CRM form being shown in Outlook wasn’t the same as the CRM form he was customizing.  He asked me why, why, why, why was this happening.
The contact form looked different than the information in outlook, except if you clicked on the contact it opened a CRM form which looked the same?!?!?!
Contact form in CRM Web
contact form

Outlook contact form but it still has fields which were removed from the contact form.
contact form outlook

So what’s the problem?

I haven’t used the CRM outlook add-in for ages, so I had to do a bit of clicking and looking around.

Searching the internet didn’t bring up anything useful, which was odd because if this was a problem then lots of people would have mentioned it.

Think, Think, Think, Think

I wondered if Outlook wasn’t refreshing properly but after un-installing and installing it still didn’t fix it.

I ended up clicking around and looking for settings, I then clicked on view.  Hmmmm Customize Reading Pane, what does that do?

custom reading pane

So I clicked it

custom reading pane 1

 AHA

The data which was being shown was the Reading Pane and the data it shows are not customizable (except you can remove some sections if you want).

What is the CRM Outlook reading pane?

The reading pane is a quick way to view contact information in a read only view.  It’s useful Microsoft have provided some quick view functionality, frustrating you can’t edit it and puzzling I couldn’t figure out where this information was coming from.

If you think of the CRM reading pane working like the normal Outlook reading pane, which shows you some details about an email without you having to open/read the email.

The CRM reading pane works in a similar way, showing you some details about the contain without having to open the contact record.  This works OK except when you have customized the contact record significantly because the new fields won’t be shown in the reading pane and fields you have removed from the form will be displayed

More information

Customize the Reading Pane in CRM for Outlook

Navigating the CRM Outlook Client

How to Hide Tabs in Reading Pane for Dynamics CRM Outlook Client

CRM 2013 – Workflow error AccessCheckEx

I was investigating a bug on CRM 2013 , I got the exception below

Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: SecLib::AccessCheckEx failed. Returned hr = -2147187962, ObjectID: f115e97d-8e19-e511-80ca-000c292122be, OwnerId: 89ed0bdd-7ecd-e411-80c7-000c292122be,  OwnerIdType: 9 and CallingUser: 2ed69167-0bcf-e411-80c7-000c292122be. ObjectTypeCode: 4200, objectBusinessUnitId: 5f964320-05f4-e411-80c9-000c292122be, AccessRights: WriteAccess Detail:
<OrganizationServiceFault xmlns:i=”http://www.w3.org/2001/XMLSchema-instance&#8221; xmlns=”http://schemas.microsoft.com/xrm/2011/Contracts”&gt;
  <ErrorCode>-2147220891</ErrorCode>
  <ErrorDetails xmlns:d2p1=”http://schemas.datacontract.org/2004/07/System.Collections.Generic”&gt;
    <KeyValuePairOfstringanyType>
      <d2p1:key>OperationStatus</d2p1:key>
      <d2p1:value xmlns:d4p1=”http://www.w3.org/2001/XMLSchema&#8221; i:type=”d4p1:string”>0</d2p1:value>
    </KeyValuePairOfstringanyType>
    <KeyValuePairOfstringanyType>
      <d2p1:key>SubErrorCode</d2p1:key>
      <d2p1:value xmlns:d4p1=”http://www.w3.org/2001/XMLSchema&#8221; i:type=”d4p1:string”>-2146233088</d2p1:value>
    </KeyValuePairOfstringanyType>
  </ErrorDetails>
  <Message>SecLib::AccessCheckEx failed. Returned hr = -2147187962, ObjectID: f115e97d-8e19-e511-80ca-000c292122be, OwnerId: 89ed0bdd-7ecd-e411-80c7-000c292122be,  OwnerIdType: 9 and CallingUser: 2ed69167-0bcf-e411-80c7-000c292122be. ObjectTypeCode: 4200, objectBusinessUnitId: 5f964320-05f4-e411-80c9-000c292122be, AccessRights: WriteAccess </Message>
  <Timestamp>2015-06-23T10:02:24.458209Z</Timestamp>
  <InnerFault i:nil=”true” />
  <TraceText>

[Microsoft.Crm.ObjectModel: Microsoft.Crm.ObjectModel.SyncWorkflowExecutionPlugin]
[0dac4467-fb18-e511-80ca-000c292122be: ]
Starting sync workflow ‘Task-Workflow’, Id: 04ac4467-fb18-e511-80ca-000c292122be
Entering ConditionStep1_step: If  Process contains data and is active
Entering SetStateStep4_step: Change record status to completed
Sync workflow ‘Task-Complete’ terminated with error ‘SecLib::AccessCheckEx failed. Returned hr = -2147187962, ObjectID: f115e97d-8e19-e511-80ca-000c292122be, OwnerId: 89ed0bdd-7ecd-e411-80c7-000c292122be,  OwnerIdType: 9 and CallingUser: 2ed69167-0bcf-e411-80c7-000c292122be. ObjectTypeCode: 4200, objectBusinessUnitId: 5f964320-05f4-e411-80c9-000c292122be, AccessRights: WriteAccess ‘
</TraceText>
</OrganizationServiceFault>

Initial thoughts on the Error

I got this error and there were a few things I found interesting

This error was surprisingly informative

The error was thrown by a non code workflow but the cause of the error was thrown by a GUI workflow which was being triggered when a workflow tried to assign an activity.

I was impressed by the level of logging which was generated by a GUI/non code workflow.

I had never thought about it but this line

Microsoft.Crm.ObjectModel: Microsoft.Crm.ObjectModel.SyncWorkflowExecutionPlugin

indicates CRM runs the GUI workflows using code, which must translate the actions into code. This is obvious but I hadn’t thought about it, until seeing the error.

You can use the callerid to find what user is doing the update and check what security roles the user has.

EntityTypeCode

In the error message you can see it mentions ObjectTypeCode

CRM 2011/2013 – Javascript to get the object type code of an entity

Each entity has an individual typecode, this CRM SDK page shows you the values of the default entities

Entity Type Code 4200 is ActivityPointer, which is interesting because the problem was being caused by an update to a task record.

Clues

AccessCheckEx failed – AccessCheckEx is something to do with security and access

In the error message you can see

AccessRights: WriteAccess

This is clearly telling us the user doesn’t have Write access, e.g. the user isn’t allow to update a certain

What was the cause

This bug was partly caused by the complexity of the CRM solution and the different customizations.

Solution complexity refer to not only the customizations which exist in the solution but the number of different customizations.  When a CRM solution has lots of different customizations e.g. workflows, plugins, business rules being triggered at the same time it makes it difficult to understand what is changing a value.

Below is what was happening

  1. A task was updated then saved
  2. This triggered a pre plugin on the task entity
  3. The plugin assigns the case record
  4. A plugin was triggered on assign of the case, which assigned all the open tasks to the new case owner
  5. The plugin(s) finished
  6. A workflow was triggered, which tried set the task to complete.

The error was thrown because the workflow was trying to update the task but the user only had privileges to update tasks they owned.

The reason this bug suddenly appeared was because the assign plugin was added and it wasn’t picked up in DEV testing because developers tested the code using users with System Admin privileges, which I have talked about before

The System Administrator role is a benefit and a curse to CRM developers

It’s tricky to test the effect of adding plugins

Having lots of different types of customizations adds to the complexity of your CRM solution, complex solutions are difficult to debug, understand and extend.

The Solution

Usually with bugs where the user doesn’t have the right security privilege the easy answer is to give the user role those security privileges.

For this bug it wasn’t the correct solution because the users only had access to tasks they owned and we didn’t want to suddenly give them permissions to update tasks they didn’t own.

The plugin code was running in a PRE plugin, so I couldn’t move the task completing code into this plugin.

The bug was becoming more tricky because I did want to keep the case assigning code in their but I didn’t want the assigning case plugin to run and assign the task to the new case owner because the task was about to completed.

My solution was to stop the assign plugin being triggered if was called by another plugin

Read how to do that in the blog below

CRM Plugins – Stopping infinite loops and understanding PluginExecutionContext.Depth

I then created a post task plugin to complete the task.  I didn’t need to do this but it seemed it would be easy to understand if all the changes were made by plugins.

There was an unsuccessful fix when I used impersonation to close the task as System Admin but the users didn’t like the tasks being closed by System Admin, they wanted the user who updated the task to complete the task.

You can read about Impersonation in plugins in the blog post below

CRM 2015 – Understanding impersonation in plugins and knowing when to use it

CRM 2015 – Understanding impersonation in plugins and knowing when to use it

Plugins are usually set to run as the calling user but sometimes you need to run a plugin with System User privileges.

Before I explain how, we should first look at the why and how you impersonate users inside a plugin

I have been writing a bit about plugins recently

For some step by step guides to creating plugins check out the CRM Code examples section on the page Hosk’s CRM Developer Articles, I created some Youtube videos CRM 2013 Plugins

What is impersonation

When you create a plugin in CRM (step by step blog post here) you write an execute method which gets passed in

IServiceProvider serviceProvider

This has lots of variables and objects such as

  • IPluginExecutionContext
  • ITracingService
  • IOrganizationServiceFactory

You use the IOrganisationServiceFactory to create a IOrganizationService.  The IOrganizationService is the CRM SDK, it provides you access to CRM programmatically .  CRM developers use the IOrganizationService (which I will often call CRMService) to

  • CRUD operation – Create, Retrieve, Update, Delete records in CRM
  • Assign records
  • Change status
  • pretty much everything you can do in CRM

Here is the code to create the IOrganizationService, taken from the Plugin class of the CRM Dev toolkit

// Obtain the Organization Service factory service from the service provider
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

// Use the factory to generate the Organization Service.
this.OrganizationService = factory.CreateOrganizationService(this.PluginExecutionContext.UserId);

When creating your plugin you will notice there is a Run in Context setting, most of the time you will choose to Run In Context of Calling User.

Create Account Plugin 1

99 percent of the time Calling User is the right choice

It’s usually the right choice to use the Calling User because any updates, retrieves or any interaction with CRM data will be done using the calling users identity and privileges.

If you visualize a plugin as an automated extension of the CRM form, it’s likely you want the the code in the plugin to run with security privileges as the calling user.  It allows you not to abdicate the need to apply security to the plugin code and pass this off the users security profile and CRM.

The PluginExecutionContext (which I explain in this blog post) has the field called UserId.  We pass this to the IOrganizationFactory to create an IOrganizationService with the user who initiated the plugin.  The good news is the CRM Dev toolkit does all this for us, so we can just chill out and get the IOrganizationService and work on the business logic.

// Use the factory to generate the Organization Service.
this.OrganizationService = factory.CreateOrganizationService(this.PluginExecutionContext.UserId);

Running the CrmService (IOrganizationService) as the calling user means you are interacting with the data in CRM as the calling user, which means

  • The IOrganizationService can only retrieve data the user can retrieve
  • When IOrganizationService updates, creates records they are stamped with the calling user
  • The plugin cannot do anything the calling user cannot do

The calling user setting adheres to the security role assigned to the calling user, integrity of your precious CRM data is kept intact.

Why impersonate System User

If running plugins as the calling user is so good, why impersonate other users or system admins.

  • What if you need to retrieve records the user doesn’t have access to?
  • What if you need to update records the user doesn’t have access to?

You might be thinking, “if the user doesn’t have access to those records, maybe the plugin shouldn’t be updating them”.

It’s a point to consider point but sometimes you want to create records or update records based on the action/status of an entity to move the code to the next stage/state.

Sometimes you want to assign a record to another user when a record goes to a certain state but you wouldn’t want users to be able to assign records.

How is running in context different from impersonation

The running in context setting on a plugin mentioned early runs the whole plugin in that context.

Impersonation allows you to run a small section of code in another context.

Impersonation gives the CRM developer more flexibility to target a particular action in a plugin they would like to run with elevation permissions.  The rest of the plugin actions can be run as

Dangers of impersonation

The downsides of impersonation is it potentially gives users running the plugin\custom workflow enhanced security privileges which could lead who we don’t want updating\deleting records doing exactly that.

When using impersonation in plugins consider accountability and audit trails.  When a plugin impersonates a system user or a different user, the impersonated user will update those records.  It can be confusing/worrying for users when looking at audit records to see System Admin updating records.

I’m sure there have been thousands of support calls querying why System Admin has been updating records.

Impersonation Code

Easy way to impersonate System User is to pass null to the CreateOrganizationService and it will run as System user, find out more in this CRM SDK article

// Use the factory to generate the Organization Service.
OrganizationServiceImpersonated = factory.CreateOrganizationService(null);

 

You can pass in a different user Id to the CreateOrganizationService to create an IOrganizationService

IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.InitiatingUserId);

The sample code in the CRM SDK article impersonates using OrganizationServiceContext.  I personally have used this

Sample: Impersonate using the ActOnBehalfOf privilege

// Retrieve the system user ID of the user to impersonate.
OrganizationServiceContext orgContext = new OrganizationServiceContext(_serviceProxy);
_userId = (from user in orgContext.CreateQuery<SystemUser>()
where user.FullName == "Kevin Cook"
select user.SystemUserId.Value).FirstOrDefault();

// To impersonate another user, set the OrganizationServiceProxy.CallerId
// property to the ID of the other user.
_serviceProxy.CallerId = _userId;

Impersonating during plugin-in registration

You can impersonate a user during plugin-registration but I’m not entirely sure why you would do this, so I’m not going to talk about.  Most CRM developer will impersonate someone inside a plugin.

If you want to learn more read

Impersonate another user

and the articles in the futher reading section

Why, What, Where, When

What is Impersonation

Impersonation in plugins/custom workflows is creating an IOrganisationService as a different user

Why use Impersonation

Use impersonation when you need to update/retrieve/delete/Create records users security roles doesn’t let them.

Where

If you don’t want to increase users security roles but still want the plugin to do a particularly action.  e.g. delete a record

When

You use impersonation in plugins/customer workflows

 

Further reading

Scott Durow has an excellent article on Impersonation

User Impersonation in Plugins, Workflow and Dialogs

CRM SDK 2015 impersonating User in plugins

Dave Berry does a good job explaining Impersonation – CRM Impersonation Explained

Awesome Pixar impersonation picture from here

Hosk’s Top CRM Articles of the week – 17th July

Article of the Week

The article of the week is my trilogy of articles on plugin code

  1. Are your CRM plugins creating technical debt?

  2. Are CRM Developers are afraid of creating classes?

  3. How to find classes

The articles look at the effect of creating plugins and putting all the code inside the plugin class, the benefits of creating classes and how to find classes when creating code.

Non Hosk article of the week

Dynamics CRM and ILMerge: The Easy Way to Merge DLLs for Plugins

It’s an old article but a good step by step guide to using ILMerge

Best of the Rest

check out the plugin tracing in CRM 2015 sp1

The ability to see the trace file in plugins will dramatically help investigating live issues.

CRM 2013 – Understanding Auditing, Tips, Tricks and Gotchas

A good long look at auditing by the Hosk.

How to handle Nulls in Dynamics CRM Calculated Fields

Interesting article on handling nulls in calculated fields

CRM 2013 – Javascript null setting oddity

A Hosk article investigating why a field wasn’t being set but delves into requirement levels and debugging

Microsoft acquires FieldOne, global provider of field service management solutions for the enterprise
video

Another new business purchased by Microsoft

Dynamics CRM: Extensions to Improve IOrganizationService

Good use of extensions to ease CRM Development

What are Preview features and how do I enable them?

New preview functionality has been added to CRM 2015, check it out

Accessing related entities fields in Calculated Fields formulas in Microsoft Dynamics CRM 2015 Online Update 1

Debugging Plug-in Made Easy for Dynamics CRM Online

A step by step guide to debugging plugins using the plugin registration tool

Microsoft Dynamics CRM not working? check these common causes

What to check if CRM stops working

Restrict customer lookup to select a specific entity records in CRM 2013/2015

Adding filters to lookups in Javascript

What’s new in CRM 2015 SP1 for developers, customizers and admins

A run down of the new features in CRM 2015 SP1

programming

Get off Your Horse and Stop Coding like a Cowboy

Second System Syndrome

interesting discussion – Over 40 years, has Software Gotten Better or Worse?

Other articles interesting the Hosk

How Bold Entrepreneurs Are Breaking $1 Million In One-Person Businesses

Microsoft ruined Nokia – WHY. Microsoft and Nokia – a marriage made in hell?

How Changing Our Product Team Structure Doubled Productivity

Annoying practices of bad recruitment consultants

Microsoft marketing manager plays the blues

Elon Musk’s high-speed Hyperloop train makes more sense for Mars than California

Here’s what happens to your brain when you give up sugar for Lent

The Stoic: 9 Principles to Help You Keep Calm in Chaos

teaching maths Asian style

What I learned from a McDonald’s Manager

Previous top picks

Hosk’s Top CRM Articles of the week – 10th July

Useful Hosk Links

Hosk list Of CRM 2013 Tools

A list and review of CRM 2013 tools, this will probably work in CRM 2015 as well

Hosk’s CRM Developer Articles

A collection of my favourite CRM Developer articles I have written

MB2-703 – CRM 2013 Customization and Configuration Certification Information

All the CRM 2013 content to help you pass the exam

HoskWisdom – Hosk Developer Quotes

 Words of Wisdom from the Hosk.  I have written over 900 articles, surely I should have said a few memorable things

How to find classes

This is the 3rd part of my trilogy of blogs on classes and code quality in plugins, the previous two parts are

  1. Are your CRM plugins creating technical debt?
  2. Are CRM Developers are afraid of creating classes?

I have written an increasing number of articles focusing on the quality and design of code, which you can find Hosk’s CRM Developer Articles

To summarise the first blog discusses the effects of creating plugins and putting the code into the plugin.

  • Complex code
  • Hard to read
  • No code reuse
  • Difficult to debug
  • Writing unit tests is hard so most CRM developers don’t bother
  • Creates duplicate code

The second blog post discusses the benefits of creating classes and using abstractions, it allows the developer to manage the effects of change whilst cr

The role of classes

  • Removes duplicate code
  • Modelling real world and abstract ideas
  • Reduces complexity
  • Manages the effects of change
  • Information hiding
  • Create reusable code

The benefits of classes

  • The code is created from many simple classes and methods
  • The code is easy to unit test
  • Well designed classes have minimal dependencies
  • Well designed classes should be able to be reused
  • Classes and method can make the code easier to understand
  • Good abstractions can be used in different projects

You should now be convinced creating classes is the way to go, so how do you find classes

Finding classes

The benefits of creating classes have been outlined above but finding classes and abstractions can be tricky.  Numerous times I have created some initial classes only to find my one class could then be broken into two or three separate classes.

The design of code emerges overtime with unit tests allowing developers to change the code and test it still works.  Development tools can help refactor the code but there is an overhead to changing existing code and tests.

The earlier you can successfully identify classes/abstractions the less time you can spend refactoring your code, so it’s worth improving the methods you use to find classes.

There are some common methods to help developers find classes which I will outline below.

NOUNS = Class, Verbs = Methods

CRM developers usually get a requirements document/functional spec.  It’s good practise to create a use case document to see what steps the end user will go through using the functionality (This will find the different paths through the customization).

The requirements document/use case can be used to find nouns and verbs to help you creates classes and methods.   Nouns give you the classes and Verbs give you the methods.

Nouns – Person/Place/Things
Verbs – Methods/Behavior/action

Using the nouns/verbs method gives you a good start identifying classes but it’s far from fool proof and will miss some classes and create duplicates.

When using this method be aware classes are not always specified as nouns, you may need to look a bit harder.

The nouns/verb method of finding classes and methods is a good start point for finding classes/methods.  When using the process keep in mind you are trying to find abstractions and common functionality in the requirements, design is an iterative process which involves understanding the problem and solution, uncovering more details as you go.

It’s common in use case to use different nouns whilst referring to the same abstraction, so you will find duplicate nouns and part of the process will involve getting rid of duplicates and merging some of the nouns together.

Code Complete 2 gives a clear definition of what an abstraction is

abstraction is the ability to view a complex operation in a simplified form.  A class interface provides an abstraction of the implementation that’s hidden behind the interface

A good way to think about classes as an interface, methods are the actions performed.  Inside a class you have hidden variables.

Finding classes, designing the methods before you start coding helps give a developer a more holistic top down view of the design.  Once a developer starts coding the perspective tends to shift more towards a bottom up approach of the functionality required.

Relationships

After identifing a list of potential classes a good method to find the relationships between those classes is to do a quick Conceptual object of those classes

Object-modeling technique

This helps to identify the interactions between classes, the goal of this task is to highlight any missing classes.

This will show you the behaviour of the classes and what classes will interact with other.  Some of these behaviours will have been found when you looked at the adjectives in the use case.

Responsibilities

It’s interesting to think about the responsibilities your classes are going to have, which class is responsible for certain data

Responsibilities can be

  • Knowledge/state an object maintains
  • Actions/methods an object will perform
  • Services/functionality provided by an object

It can be useful to CRC models

CRC models shows the Colloborators and Responsiblities of a class, below is a useful video

https://www.youtube.com/watch?v=5IpsMwxL37k&list=PLqlI1RpjIS59ziAx7YBqQ0rtyAcpgdsjm&index=25

Find Common Functionality

Classes are also in common functionality and actions used by other classes.

It can help to create class diagrams to see the classes and the interactions between classes.  This can help you find missing classes.

The next stage is create the classes, code and unit tests.  Once the code is working you can think about refactoring/tidying the code and thinking about apply SOLID principles

A good way of finding 2 or more classes within one class is to check the class is focused and doing one thing e.g. The Single Responsibility principle.

A quick way to check if a class is doing more than one thing is the name of the class.  The class should clearly describe what it is/what it does.  Badly named classes often are badly named because they are doing more than one thing.

Actions, manager, Super

Class smells

Here is a list of class smells which often indicate the class is doing to much and could be split into more separate classes

  • Difficult to name the class?  This is usually a sign the class is doing more than one thing
  • Cohesive.  Are all class variables used by most methods, do some methods not use certain variables.  A lack of cohesion is usually a sign a class can be broken out.
  • To many methods.  A high number of methods usually means high complexity, indicating the class is a candidate for refactoring to simplify the code
  • Method length (in lines) – a class bigger than 200 or 300 hundred lines is to big

When checking classes you are often checking for cohesion and if the class can be broken into smaller more cohesive classes.

Cohesion when used to describe design can confuse some readers, so here is wiki’s definition of cohesion

In computer programming, cohesion refers to the degree to which the elements of a module belong together.  Thus, it is a measure of how strongly related each piece of functionality expressed by the source code of a software module is.

Cohesion is the concept all the variables and methods in the class fitting together under the name and purpose of the class.  A class should have a single responsibility, a single purpose.  If a class has more than one purpose then it should be split up.

Example

Here is a quick example

ATM Machine

A bank customer must be able to make withdrawals from the ATM machine using their card.  The card must be validated before the ATM will give money.

ATM machine will check the user has at least the amount of money to be withdrawn in the account.

The bank customer can make a balance enquiry.

Nouns

  • Customer
  • ATM Machine
  • Card
  • money

verbs

  • withdrawn
  • check
  • validated

Further reading

OOSC-2: HOW TO FIND THE CLASSES

From the awesome Bertrand Meyer.  I found the article above very useful

Are CRM Developers are afraid of creating classes?

I have seen lots of CRM code and my initial thoughts are CRM developers don’t seem to create many classes or spend much time designing their code.  In this blog post I will discuss the effects of not creating classes and explain the benefits of classes and abstractions.

Are CRM Developers afraid of creating classes?

The problem seems to be self reinforcing.  Previous CRM projects contain few classes and most of the code exists in the plugin, this sets an unspoken standard which encourages developers to not create classes.

This is a mixture of a safety in numbers/wisdom of crowds approach, it could be seen as consistency and a standard approach to CRM development is good.  Consistency in CRM development helps developers maintain, debug and extend CRM projects.

In the case of putting code in the plugin and not creating classes I think it’s bad practise and every plugin you add creates more technical debt for the CRM project and CRM projects quickly resemble legacy projects with complex CRM customizations

The end result is complex code doing lots of things and impossible to reuse and extremely difficult to work with (maintain, debug, read, etc).

To not use classes and put all or the bulk of the code in the plugin class

  • makes it impossible to reuse code
  • create complex code which does many things
  • creates duplicate code
  • create code which is hard to understand
  • Code is very difficult to test

CRM plugins are often small, focused code but to not create classes or abstractions is to create a code base technical debt.  This debt is paid back when CRM developers take longer to interact with the code in the future.

Plugins with few or no classes results in each developer creating new code every time because it’s impossible to reuse any of the code in the other plugins.

If CRM developers are not creating classes they are creating legacy code and plugins contain monster methods – Hosk

Boy Scout rule

The focus when creating code should be to keep the quality high, test everything and keep code as simple as possible.

When you create plugins or every time you make a code change you make you should leave the code in better state than you found it.  Why you should write code and customizations like a boy scout

Quality of code is fundamental to the long term success of a CRM project and as soon as you lower your coding standards and let in bad code, it will soon spread Bad code is like a virus, don’t get infected

What is the role of Classes in programming

I advocate no code logic should be added to the plugin class except a call to a class passing in the entity, IOrganisationService, ITracing.

Putting logic in a plugin creates complex code, which is difficult to unit test but there are other reasons to create classes which are listed below

No Duplicate code

Duplicate code is one of the worst code smells and it has multiple bad side effects

  • More code = more potential bugs
  • duplicate code = bug fixing can result in multiple fixes
  • bug fix one set = miss out changing duplicate code, which one is right?

When ever you find duplicate code or are about to create duplicate code, take the opportunity to find the common behaviour and abstract it into a class.  This will enable you to reuse this single piece of code in many places.

Using classes and functions is the primary weapon against duplicate code because you are logically sorting code in logical class/method, which will allow developers to easily find and use it.

Modelling real world and abstract ideas

Classes allow you to model real world objects (account) and abstract concepts (printing, validating).  The benefit is you can split up the code into logical abstractions which give clarity to the intent of the code.

CRM out of the box models plenty of real world objects

  • Accounts
  • Contacts
  • Opportunities
  • Phone Calls

Abstract classes

  • Security role
  • Solution
  • Behaviours

You can create classes to model behaviours, this could be things like validating, printing, logging.  These behaviours can be use in composition and used in multiple classes.  The benefit of modelling behaviours is reuse

  • Create abstract objects
  • Create real world objects

Reduce complexity

Classes reduce complexity by splitting code into abstract or logical sections.  The term abstract can be confusing, instead replace it with logical groups.  Splitting code into logical groups organises the code into smaller/reusable sections.

Breaking the code into classes creates cohesive code and reducing dependencies between classes.

Creating well named classes with well named methods reduces complexity and makes the code using those methods and classes easier to read/understand.

Creating classes and methods allows you to create descriptive methods, e.g. call the a print method is easier to understand than reading all the lines of code needed to print.  At a high level you might not need to know all the details of printing.

Manage the effect of change

Classes help reduce the effects of change by removing dependencies between classes (assuming the classes are well designed).  Using abstract classes can remove the effects of change on the code using the abstract classes.

Well designed code can make it easy to add new types by encapsulating what varies and programming to interfaces.  Adding a new type should not effect the other types or the code using the abstract class.

Managing the effects of change can reduce dependences and stop changes in code unexpectedly breaking other parts of the system.  You could rename this to limiting the effects of change by reducing the ripple effect change has on badly designed code.

Information hiding

Read my blog post Good coding practices – Information hiding

hold data instead of lots of parameters

You can structure classes to hold the data instead of passing lots of variables between methods.  This makes the code easier to understand and interact with.

Create reusable code

Many CRM projects I have worked on/inspected have had almost no code reuse partly due to the lack of classes created.  Part of the reason is attitude, CRM developers don’t view creating reusable code as a priority.

CRM organised internal entities to make it easier to understand how it works.  If we take security roles as an example.

The security role entity contains the main privileges which have a value of TRUE or FALSE and one of the four access levels Global, Business Child, Business unit, user.

Every time we add a new entity, we can set privileges for Create, Read, Write, Delete, Append, Append To, Assign, Share.

Whilst thinking about the example above I would except Privilege to be a separate class but we can see understanding the data in this structure is easier.

The benefits of designing classes 

The clean coder has a good change on classes which talks about change isolating change

Needs will change, therefore code will change. We learned in OO 101 that there are concrete classes, which contain implementation details (code), and abstract classes, which
represent concepts only. A client class depending upon concrete details is at risk when those details change. We can introduce interfaces and abstract classes to help isolate the impact of those details.

Abstraction and modularity allows developers to work on separate parts of a system without having a detailed knowledge of the whole system.

Plugins allow developers to create new plugins without affecting other plugins.  The crm dev needs to check there are no other plugins being triggered on the same entity.  Good design of the code is based on on the plugin interface and not the concrete class e.g. your plugin.

Well designed classes have many benefits

  • The code is created from many simple classes and methods
  • The code is easy to unit test
  • Well designed classes have minimal dependencies
  • Well designed classes should be able to be reused
  • Classes and method can make the code easier to understand
  • Good abstractions can be used in different projects

Coding to an interface

The benefits of coding to an interface and using classes behind the interface is you limit the effects of change behind the interface.

You can add new types behind the interface without affecting any of the code which uses the interface.

A quick example is routing records to different users or teams, for this you could create an interface called Route and then concrete classes will contain the routing details and default value of the users/teams.

Route – Interface

  • RouteToTeam
    • RouteToDefaultTeam
    • RouteToSalesTeam
    • RouteToMarketingTeam
  • RouteToUser
    • RouteToSalesManager
    • RouteToCaseManager

The benefits of coding to an interface and using classes

  1. Any code using the Route interface will be unaware of what specific type of route they are using.
  2. The code calling the interface has no knowledge of what objects, variables are used to route, it calls the Route interface methods
  3. Its easy to add new Routes which will involve changing minimal amount of code
  4. The code using the Interface is decoupled from the concrete classes
  5. The effects of change are restrained by the interface
  6. Easy to test
  7. Selecting the type can be done dynamically at runtime

Dependency Inversion Principle (DIP)

Reading about the Dependency Inversion Principle (DIP) helped me understand abstractions and the benefits of using them.  To remind you what DIP is

Depend on abstractions, not on concretions.

Wiki adds two more points to help understand

A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend on details. Details should depend on abstractions.

I highly recommend you read Uncle Bobs article The Dependency Inversion Principle, where he explains it a lot better than me.

This article DIP in the Wild has a good example of using DIP which helps understand  the concept and it’s usage in developer life.

Abstract ideas can be tricky to understand, to make this easier to understand think of black boxes.

Black boxes are code which works but the user of the black box doesn’t know how the code works inside the black box.  The internal code can change but the consumers of the black box wouldn’t know.

Change has been isolated inside the black box, Interfaces and abstract classes operate as black boxes hiding the change behind them.   Any code which interacts with an interface/abstract class won’t need to change if the internal workings behind the interfaces/abstract classes change.

A good example is using the CRM SDK to interact with the CRM database.  Microsoft can change how the internal workings of the CRM SDK change and can change the CRM database structure (in CRM 2015 they removed CRM database extension table).

Microsoft removed a whole table but CRM developers who used the SDK wouldn’t have noticed any difference (I didn’t notice) but those who developed code/reports directly against the CRM table would suddenly find their code/reports no longer worked when they upgraded to CRM 2015.

The next blog in the series is how to find Classes