Wednesday, 19 March 2014

C# Dependency Injection tutorial (Inversion of Control Tutorial)

C# Dependency Injection tutorial (Inversion of Control Tutorial)

 Reference

http://dotnetanalysis.blogspot.in/2011/11/dependency-inversion-or-inversion-of.html


Aim of Dependency Injection:

Referring to the image below. Suppose when the console application was initially built, there was no XML or Text File. But later on an XML datasource is added (and a corresponding GetMessageFromXML class). And a few more months down the line a text file datasource. Our aim is write the code in a way that, when a new datasource is added, only the calling datasource from Main method needs to be updated. The code in DisplayMessage Class shouldn't need to change to accommodate a new datasource.


 
Description: https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_5kG0bzYOtLriQPuLSCSw953b97IwI5Qu6YMrQVyj0VePxJ2daw0T5_GT9wKkCZIluhhNJY8jSL2rXM7CUL3-3Zkj5Tdb1iWe6ICmHaW_q5FSn_TGyVnt-nTu4T6vtWjSdjwJutfnnubi/s640/DependencyInversion.jpg
 


















Bad code without Dependency Injection:

 What I will try to show you here is how in a bad code, changing one part of the code requires changes in other parts of the code. And how after applying dependency injection,  I could make different parts of code, independent of each other.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
 
 
    class Program
    {
        static void Main(string[] args)
        {
            DisplayMessage dm = new DisplayMessage();
            dm.ShowMessage();
        }
    }
 
    public class DisplayMessage
    {
        GetMessageFromDatabase Gmd;
 
        public DisplayMessage()
        {
            Gmd = new GetMessageFromDatabase();
        }
        public void ShowMessage()
        {
            Console.WriteLine(Gmd.GetMessage());
            Console.ReadLine();
        }
    }
 
    public class GetMessageFromDatabase
    {
        public string GetMessage()
        {
            //Pretend this comes from the database
            return "Hi from database";
        }
    }
 
 
}
 
 
 
Everything works fine. Suppose 3 months down the line based on the argument passed into the Main method, I have to pull data either from a database or an xml file. To make that happen I add a class GetMessageFromXML to my code. Also I make a slight modification to my Main  method. The code now looks like below.
 
 
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
 
 
    class Program
    {
        static void Main(string[] args)
        {
            DisplayMessage dm = newDisplayMessage(args[0].ToString());
 
            dm.ShowMessage();
        }
    }
 
 
    public class DisplayMessage
    {
        string source;
 
        public DisplayMessage(string s)
        {
            source = s;
 
        }
        public void ShowMessage()
        {
            if (source.ToUpper() == "DATABASE")
            {
                GetMessageFromDatabase Gmd = newGetMessageFromDatabase();
                Console.WriteLine(Gmd.GetMessage());
                Console.ReadLine();
            }
            else if (source.ToUpper() == "XML")
            {
                GetMessageFromXML Gmx = new GetMessageFromXML();
                Console.WriteLine(Gmx.GetMessage());
                Console.ReadLine();
            }
          
        }
    }
 
 
 
    public class GetMessageFromDatabase
    {
        public string GetMessage()
        {
            //Pretend this comes from the database
            return "Hi from database";
        }
    }
 
 
    public class GetMessageFromXML
    {
        public string GetMessage()
        {
            //Pretend this comes from an XML file
            return "Hi from XML";
        }
    }
 
 
}
 
Now another 2 months later suppose I also need to read data from a text file based on the input parameter to the main method. What would I do? I would add another class GetMessageFromTextFile . Also I would have to modify the class DisplayMessage
 
Do you see how dependent the class DisplayMessage is on the implementation (that is depending on where the data is being fetched from) ?  

Inversion of Control attempts to make the class 
DisplayMessage  and the data fetching classes totally independent of each other. 
 
Inversion of control is usually achieved by applying dependency injection. There are three popular ways of applying dependency injection  namely
·                     Constructor Injection
·                     Method Injection
·                     Property Injection

Code with Dependency Injection: 

In the code below, I have demonstrated inversion of control using constructor injection
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    public interface IGetData
    {
        string GetMessage();
    }
 
 
    class Program
    {
        static void Main(string[] args)
        {
            IGetData IG;
 
            string source = args[0].ToString();
 
            if (source.ToUpper() == "DATABASE")
            {
                IG = new GetMessageFromDatabase();
            }
            else if (source.ToUpper() == "XML")
            {
                IG = new GetMessageFromXML();
            }
            else if (source.ToUpper() == "TEXT")
            {
                IG = new GetMessageFromTextFile();
            }
            else
            {
                IG = new GetMessageFromDatabase();//default set to database
            }
 
            DisplayMessage dm = new DisplayMessage(IG);
            dm.ShowMessage();
 
 
        }
    }
 
 
    public class DisplayMessage
    {
        IGetData IGLocal;
 
        public DisplayMessage(IGetData IG)
        {
            IGLocal = IG;
 
        }
        public void ShowMessage()
        {
            Console.WriteLine(IGLocal.GetMessage());
 
        }
    }
 
 
 
    public class GetMessageFromDatabase : IGetData
    {
        public string GetMessage()
        {
            //Pretend this comes from the database
            return "Hi from database";
        }
    }
 
 
    public class GetMessageFromXML : IGetData
    {
        public string GetMessage()
        {
            //Pretend this comes from an XML file
            return "Hi from XML";
        }
    }
 
    public class GetMessageFromTextFile : IGetData
    {
        public string GetMessage()
        {
            //Pretend this comes from an Text file
            return "Hi from Text file";
        }
    }
}
 

Now like you see above, injecting the dependencies through the constructor, I am decoupling 
DisplayMessage class from the class GetMessageFromDatabase or any other class that the DisplayMessage class might end up utilizing. I can add as many new classes as I want, to fetch data, without modifying the DisplayMessage class, as long as they inherit from the IGetData interface.
So what happened here is that, everything depends on the interface. Which is ideal.



Now you might argue that I actually ended up shifting the dependency to the 
Main method.  You are absolutely correct. For a console application the main method (or a piece of code called from the main method) is an acceptable composition root (the place where we decide which implementation to use for an interface). The composition root is always located at the startup code of an application. (For web applications that would be global.asax.cs).

In most practical applications you would end up using an Ioc container such as Ninject or Autofac.  These softwares make it possible to inject dependencies (at compile time as well as run time) with much lesser code. Check
 this for a super simple example of autofac.
 
 
 



The specified application identifier is invalid or does not exist

The specified application identifier is invalid or does not exist

Error:
The specified application identifier cbd25585-947e-4b9d-8686-ed695101ed9a is invalid or does not exist.
Fix:
Resolution2 (Recommended): To get away with the above error message. Create a ClientID and ClientSecret using "_layouts/15/appregnew.aspx" page. Basically, you need to register your app on the target SharePoint farm where you intend to deploy your app. And then use those generated ClientID and ClientSecret while packaging your app in your dev environment.
Reference

Setting up your App domain for SharePoint 2013

Saturday, 15 March 2014

Creating a custom WCF REST service for SharePoint 2013

Creating a custom WCF REST service for SharePoint 2013



  • Create a new SharePoint 2013 Empty Project as a Farm Solution
  • Add a WCF Service Application project to your solution
  • Add the ISAPI mapped folder to your SharePoint project
  • Drag the Service1.svc and Service1.svc.cs files from the WCF project to the SharePoint project under the ISAPI mapped folder
  • Drag the IService1.cs file from the WCF project to the SharePoint project
  • Add the WCF references to your SharePoint project

    • System.Runtime.Serialization
    • System.ServiceModel
    • System.ServiceModel.Web

  • Change the namespace from WcfService1 to your assembly's namespace (e.g., MyRestService) in Service1.svc.cs and IService1.cs
  • Build your project
  • Using the Visual Studio Command Prompt, go to the project output folder of the SharePoint project
  • Get the PublicKeyToken for your assembly using the strong name utility

    • sn -T MyRestService.dll

  • In Service1.svc, change the Service attribute on the ServiceHost directive to be in the following format:



  • 1
    <%@ ServiceHost Language="C#" Debug="true" Service="{NameSpace}.{ServiceName}, {AssemblyName}, Version=1.0.0.0, Culture=Neutral, PublicKeyToken={PublicKeyToken}" CodeBehind="Service1.svc.cs" %>



      • Replace the tokens here, represented by {Token} with the appropriate values for your project. e.g., 
      1
      <%@ ServiceHost Language="C#" Debug="true" Service="MyRestService.Service1, MyRestService, Version=1.0.0.0, Culture=Neutral, PublicKeyToken={PublicKeyToken}" CodeBehind="Service1.svc.cs" %>
    1. Deploy your solution
    2. Verify the service loads
      • Note: see below for troubleshooting a common error.
    3. Add a HelloWorld operation to your contract, IService1.cs that is set up for REST.
    4. 1
      2
      3
      [OperationContract]
      [WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "HelloWorld")
      string HelloWorld();
    5. Implement the operation in Service1.svc.cs




    6. public string HelloWorld()
      {
          return "Hello World";
      }
    7. Update web.config with the appropriate info for your service



















    <behaviors>
        <serviceBehaviors>
            <behavior name="Service1ServiceBehavior">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
        </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="jsonBehavior">
                <webHttp />
            </behavior    </endpointBehaviors>
    </behaviors>
    <services>
        <service name="MyRestService.Service1" behaviorConfiguration="Service1ServiceBehavior">
            <endpoint address="" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="MyRestService.IService1" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
    </services>


    1. Test your HelloWorld operation and you should see the following:


    Troubleshooting

    • If you get an error that says "This collection already contains an address with scheme http.  There can be at most one address per scheme in this collection." this is due to having multiple bindings in IIS, which is common in SharePoint when you have multiple Alternate Access Mappings.
    This collection already contains an address with scheme http.  There can be at most one address per scheme in this collection.



    The property or field 'Title' has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.

    The property or field 'Title' has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.

    Fix:

     Usually we get this error when we try to use a property before calling ExecuteQuery();
    I find a similar thread here you must call executeQuery and use the property.

    Reference:

    http://social.msdn.microsoft.com/Forums/en-US/f0b4955b-56a2-4af4-b55c-f894b7bf2baa/the-property-or-field-has-not-been-initialized-it-has-not-been-requested-or-the-request-has-not?forum=sharepointdevelopmentlegacy

    http://social.technet.microsoft.com/Forums/sharepoint/en-US/245bae70-0fd7-4d17-9f40-5489db537d65/exception-in-clientcontext-class-while-try-to-get-sharepoint-object?forum=sharepointdevelopmentprevious