четверг, марта 25, 2010

Конфигурация WCF Service без app.config

Недавно столкнулся с такой задачей - потребовалось произвести настройку WCF службы напрямую из кода, т.е. без использования .config файла приложения. Потребовалось немало времени, чтобы выгуглить вменяемые примеры, потому ту часть решения, которая получилась у
меня, выкладываю сюда, надеюсь пригодится кому в качестве отправной точки...


Итак, исходный конфиг:

<system.servicemodel>
            <!--  диагностика - включим трассировку сообщений, который будут сохраняться в файлах, указанных листенерах -->
            <diagnostics>
              <messagelogging logmalformedmessages="true" logmessagesattransportlevel="true">
            </messagelogging>

            <behaviors>
              <servicebehaviors>
                <behavior name="SampleService.Behavior.Service">

                  <!--  отдаем пока исключение в процесс отдладки -->
                  <servicedebug includeexceptiondetailinfaults="true">

                  <!--  разрешаем сервису отдавтать описание - wsdl -->
                  <servicemetadata  httpgetenabled="true">

                </servicemetadata >
              </servicedebug>

            </behavior>

            <!--  привязки и их настройки  -->
            <bindings>
              <webhttpbinding>
                <binding name="SampleService.EndPointConfiguration.Web">
                         allowCookies="true"
                         closeTimeout="00:10:00"
                         openTimeout="00:10:00"
                         receiveTimeout="00:10:00"
                         sendTimeout="00:10:00"
                         bypassProxyOnLocal="false"
                         maxBufferPoolSize="10000000"
                         useDefaultWebProxy="true"
                         maxReceivedMessageSize="4096">
                  <security mode="None"></security>
                </binding>
              </webhttpbinding>
            </bindings>

            <services>
              <!--  указываем сервис  -->
              <service  name="SampleService">
                        behaviorConfiguration="SampleService.Behavior.Service">
                <endpoint address="http://127.0.0.1:9999/">
                                      binding="webHttpBinding"
                          behaviorConfiguration="SampleService.Behavior.EndPointBehavior"
                                      bindingConfiguration="SampleService.EndPointConfiguration.Web"
                                      contract="SampleService.IServiceContract">
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
                <host>
                  <baseaddresses>
                    <add baseaddress="http://127.0.0.1:9999/">
                  </add>
                </baseaddresses>
              </host>
            </endpoint>


          </service >
</system.servicemodel>


превращается в пару строку из ini файла:

[sample_service]
host=127.0.0.1
port=9999 

c# код программного создания конечной точки и описанных поведений, аналогичных тем, которые были ранее в .config, приведен ниже:

            #region binding
            WebHttpBinding  binding = new WebHttpBinding();
            binding.AllowCookies = true;
            
            binding.CloseTimeout = TimeSpan.FromMinutes(10);
            binding.SendTimeout = TimeSpan.FromMinutes( 10 );
            binding.OpenTimeout = TimeSpan.FromMinutes( 10 );
            binding.ReceiveTimeout = TimeSpan.FromMinutes( 10 );

            binding.BypassProxyOnLocal = false;
            binding.UseDefaultWebProxy = true;
            
            binding.MaxBufferPoolSize = 1000000;
            binding.MaxReceivedMessageSize = 1000000;

            binding.Security.Mode = WebHttpSecurityMode.None;
            #endregion

            #region endpoint adress
            
            Uri endpointUri = GlobalConfiguration.SETTINGS_SAMPLE_SERVICE_BASE_ADDRESS;
            Uri mexEndpointUri = new Uri(String.Format("{0}/mex", endpointUri.ToString()));
            #endregion

            SampleServiceHost.Instance = new ServiceHost(typeof(SampleService), endpointUri);

            #region wcf behaviour setup

            //  behoviours
            SampleServiceHost.Instance.Description.Behaviors.Clear();

            ServiceBehaviorAttribute behaviour = new ServiceBehaviorAttribute();
            behaviour.InstanceContextMode = InstanceContextMode.Single;
            behaviour.ConcurrencyMode = ConcurrencyMode.Single;

            SampleServiceHost.Instance.Description.Behaviors.Add(behaviour);


            ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior();
            serviceMetadataBehavior.HttpGetEnabled = true;
            SampleServiceHost.Instance.Description.Behaviors.Add(serviceMetadataBehavior);


            ServiceDebugBehavior serviceDebugBehavior = new ServiceDebugBehavior();
            serviceDebugBehavior.HttpHelpPageEnabled = true;
            serviceDebugBehavior.HttpsHelpPageEnabled = true;
            serviceDebugBehavior.IncludeExceptionDetailInFaults = true;
            SampleServiceHost.Instance.Description.Behaviors.Add(serviceDebugBehavior);


            #endregion

            
            //  listening end point
            SampleServiceHost.Instance.AddServiceEndpoint(typeof(SampleService.IServiceContract), binding, endpointUri.ToString()).Behaviors.Add(new WebHttpBehavior());
            //  and mex endpoint
            SampleServiceHost.Instance.AddServiceEndpoint(typeof(IMetadataExchange), binding, mexEndpointUri.ToString());

            //  start service
            SampleServiceHost.Instance.Open();


2 комментария:

Алексей комментирует...

У меня сервис паходу почему то не может прочесть конфиг, поэтому я решил то же написать конфигурацию в коде. Но не понимаю как отключить использование app.config

duШes комментирует...

Если речь идет о windows service, то прочесть он его не может по разным причинам, одна из них - конфиг должен лежать в %windir%/system32...

В моем случае речь шла не о том, что бы отказаться от использования конфига (наоборот, конфиг снаружи приложения очень даже полезная вещь), а о том, чтобы использовать конфигурационные установки из файла другого формата, более легкого для понимания и настройки