unity, WCF and registerInstance

Feb 22, 2010 at 8:33 AM

Hi,

I'm starting to learn how to use Dependency Injection with Unity in WCF application. I think I have managed to modify the code from codeproject which shows how to use WCF in Winforms to use parameterised constructor by using Unity.ServiceModel library from this blog. That's one step. For my real application, I need to inject existing instance as WCF Service constructor parameter. As I read from Unity documentation there is RegisterInstance which I think will do what I need, but I still can't get it working. This is the service interface and implementation from the codeproject article mentioned before:

    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public interface IServicePatient
    {
        [OperationContract]
        Patient GetPatient(Int32 index);

        [OperationContract]
        void SetPatient(Int32 index, Patient patient);
    }

    public class PatientService : IServicePatient
    {
        IPatientData pData;

        public PatientService(IPatientData pData)
        {
            this.pData = pData;
        }

        public Patient GetPatient(Int32 index)
        {
            return pData.GetPatient(index);
        }

        public void SetPatient(Int32 index, Patient patient)
        {
            pData.SetPatient(index, patient);
        }
    }

    public interface IPatientData
    {
        Patient GetPatient(Int32 index);

        void SetPatient(Int32 index, Patient patient);
    }

    public class PatientData : IPatientData
    {
        Patient[] pat = null;

        public PatientData()
        {
            pat = new Patient[3];

            pat[0] = new Patient();
            pat[0].FirstName = "Bob";
            pat[0].LastName = "Chandler";

            pat[1] = new Patient();
            pat[1].FirstName = "Joe";
            pat[1].LastName = "Klink";

            pat[2] = new Patient();
            pat[2].FirstName = "Sally";
            pat[2].LastName = "Wilson";
        }

        public Patient GetPatient(Int32 index)
        {
            if (index <= pat.GetUpperBound(0) && index > -1)
                return pat[index];
            else
                return new Patient();
        }

        public void SetPatient(Int32 index, Patient patient)
        {
            if (index <= pat.GetUpperBound(0) && index > -1)
                pat[index] = patient;
        }
    }

    [DataContract]
    public class Patient
    {
        string firstName;
        string lastName;

        [DataMember]
        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }
        [DataMember]
        public string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }
    }

While my App.config :

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, 
             Microsoft.Practices.Unity.Configuration, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
  </configSections>

  <unity>
    
    <typeAliases>
      <typeAlias alias="external"
         type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager, Microsoft.Practices.Unity" />
    </typeAliases>
    
    <containers>
      <container>
        <types>
          <type type="TestService.IPatientData, TestService" mapTo="TestService.PatientData, TestService" >
            <lifetime type="external"/>
          </type>
        </types>        
      </container>
    </containers>
    
  </unity>
  
  <system.serviceModel>
    <services>
      <service name="TestService.PatientService" behaviorConfiguration="Behaviors1">
        <endpoint address="net.tcp://localhost:2202/PatientServiceTest" binding="netTcpBinding"
                  bindingConfiguration="Binding1" contract="TestService.IServicePatient"/>
      </service>
    </services>

    <bindings>
      <netTcpBinding>
        <binding name="Binding1">
          <security mode="None">
            <transport protectionLevel="None" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="Behaviors1">
          <unity/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    
    <extensions>
      <behaviorExtensions>
        <add name="unity" type="Unity.ServiceModel.InjectionElement, Unity.ServiceModel, 
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
"/> </behaviorExtensions> </extensions>
</system.serviceModel> </configuration>

And this is how I call the service

                //IPatientData thePatientData = new PatientData();

                //IUnityContainer myContainer = new UnityContainer();
                //UnityConfigurationSection section
                //    = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
                //section.Containers["containerOne"].Configure(myContainer);

                //myContainer.RegisterInstance<IPatientData>(thePatientData,
                //                new ExternallyControlledLifetimeManager());
           
                myServiceHost = new ServiceHost(typeof(PatientService));
                myServiceHost.Open();

The commented part is how I tried to use RegisterInstance to map IPatientData to existing instance thePatientData. It failed with argument null exception. Perhaps I missed something here. Any suggestion or help would be helpful. 

Thank you.

Regards,

Arif

<!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning /> <w:ValidateAgainstSchemas /> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:BreakWrappedTables /> <w:SnapToGridInCell /> <w:WrapTextWithPunct /> <w:UseAsianBreakRules /> <w:DontGrowAutofit /> <w:UseFELayout /> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><!--[if !mso]> <object classid="clsid:38481807-CA0E-42D2-BF39-B33AF135CC4D" id=ieooui> </object> <mce:style><! st1\:*{behavior:url(#ieooui) } --> <!--[endif]--><!-- /* Font Definitions */ @font-face {font-family:Batang; panose-1:2 3 6 0 0 1 1 1 1 1; mso-font-alt:바탕; mso-font-charset:129; mso-generic-font-family:auto; mso-font-format:other; mso-font-pitch:fixed; mso-font-signature:1 151388160 16 0 524288 0;} @font-face {font-family:"\@Batang"; panose-1:2 3 6 0 0 1 1 1 1 1; mso-font-charset:129; mso-generic-font-family:roman; mso-font-pitch:variable; mso-font-signature:-1342176593 1775729915 48 0 524447 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0mm; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:Batang;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} --><!--[if gte mso 10]> <mce:style><! /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0mm 5.4pt 0mm 5.4pt; mso-para-margin:0mm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} --> <!--[endif]-->

    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]

    public interface IServicePatient

    {

        [OperationContract]

        Patient GetPatient(Int32 index);

 

        [OperationContract]

        void SetPatient(Int32 index, Patient patient);

    }

 

    public class PatientService : IServicePatient

    {

        IPatientData pData;

 

        public PatientService(IPatientData pData)

        {

            this.pData = pData;

        }

 

        public Patient GetPatient(Int32 index)

        {

            return pData.GetPatient(index);

        }

 

        public void SetPatient(Int32 index, Patient patient)

        {

            pData.SetPatient(index, patient);

        }

    }

 

    public interface IPatientData

    {

        Patient GetPatient(Int32 index);

 

        void SetPatient(Int32 index, Patient patient);

    }

 

    public class PatientData : IPatientData

    {

        Patient[] pat = null;

 

        public PatientData()

        {

            pat = new Patient[3];

 

            pat[0] = new Patient();

            pat[0].FirstName = "Bob";

            pat[0].LastName = "Chandler";

 

            pat[1] = new Patient();

            pat[1].FirstName = "Joe";

            pat[1].LastName = "Klink";

 

            pat[2] = new Patient();

            pat[2].FirstName = "Sally";

            pat[2].LastName = "Wilson";

        }

 

        public Patient GetPatient(Int32 index)

        {

 

            if (index <= pat.GetUpperBound(0) && index > -1)

                return pat[index];

            else

                return new Patient();

        }

 

        public void SetPatient(Int32 index, Patient patient)

        {

            if (index <= pat.GetUpperBound(0) && index > -1)

                pat[index] = patient;

        }

    }

 

    [DataContract]

    public class Patient

    {

        string firstName;

        string lastName;

 

        [DataMember]

        public string FirstName

        {

            get { return firstName; }

            set { firstName = value; }

        }

        [DataMember]

        public string LastName

        {

            get { return lastName; }

            set { lastName = value; }

        }

    }