2

I have a WCF Service running and a client that I have working however currently the I have referenced the service in my client.

I would like to create the client reference dynamically.

Here is my config file:

<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=e77a5e561934e089" requirePermission="false" /> </configSections> <system.serviceModel> <services> <!-- This section is optional with the new configuration model introduced in .NET Framework 4. --> <service name="Service.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior"> <host> <baseAddresses> <add baseAddress="http://xx.xx.xx.xx:20001/Service/service" /> </baseAddresses> </host> <!-- this endpoint is exposed at the base address provided by host: http://xx.xx.xx.xx:20001/Service/service --> <endpoint address="" binding="wsHttpBinding" contract="Service.IReportData" bindingConfiguration="CustomBinding" /> <!-- the mex endpoint is exposed at http://xx.xx.xx.xx:20001/Service/service/mex --> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <bindings> <wsHttpBinding> <binding name="CustomBinding" closeTimeout="00:02:00" openTimeout="00:02:00" receiveTimeout="00:10:00" sendTimeout="00:02:00" maxReceivedMessageSize="2147483647"> <security mode="None"> <transport clientCredentialType="None" /> <message establishSecurityContext="false" /> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="CalculatorServiceBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="True" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> <system.data> <DbProviderFactories> <remove invariant="System.Data.SQLite.EF6" /> <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" /> </DbProviderFactories> </system.data> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <parameter value="v11.0" /> </parameters> </defaultConnectionFactory> <providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" /> </providers> </entityFramework> </configuration> 

I have been googling for about a week and found the following code snippet that I have been trying to use that I found on stackoverflow.

The link to the post where I found it is: Configure wcf service programmatically

public virtual ChannelFactory<T> Proxy<T>(string address) { //Validate Address if (string.IsNullOrEmpty(address)) throw new ArgumentNullException("Address can not be null or empty."); //Address EndpointAddress endpointAddress = new EndpointAddress(address); //Binding WSHttpBinding wsHttpBinding = new WSHttpBinding(SecurityMode.None, false); wsHttpBinding.OpenTimeout = wsHttpBinding.CloseTimeout = new TimeSpan(0, 1, 0); wsHttpBinding.ReceiveTimeout = wsHttpBinding.SendTimeout = new TimeSpan(0, 10, 0); wsHttpBinding.MaxReceivedMessageSize = wsHttpBinding.MaxBufferPoolSize = 2147483647; wsHttpBinding.BypassProxyOnLocal = wsHttpBinding.AllowCookies = wsHttpBinding.TransactionFlow = false; wsHttpBinding.MessageEncoding = WSMessageEncoding.Text; wsHttpBinding.TextEncoding = Encoding.UTF8; wsHttpBinding.UseDefaultWebProxy = true; wsHttpBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard; wsHttpBinding.ReaderQuotas = new XmlDictionaryReaderQuotas(); //ReaderQuotas, setting to Max wsHttpBinding.ReaderQuotas.MaxArrayLength = wsHttpBinding.ReaderQuotas.MaxBytesPerRead = 2147483647; wsHttpBinding.ReaderQuotas.MaxStringContentLength = wsHttpBinding.ReaderQuotas.MaxNameTableCharCount = 2147483647; wsHttpBinding.ReaderQuotas.MaxDepth = 2147483647; //Create the Proxy ChannelFactory<T> proxy = new ChannelFactory<T>(wsHttpBinding, endpointAddress); //Sets the MaxItemsInObjectGraph, so that client can receive large objects foreach (var operation in proxy.Endpoint.Contract.Operations) { DataContractSerializerOperationBehavior operationBehavior = operation.Behaviors.Find<DataContractSerializerOperationBehavior>(); //If DataContractSerializerOperationBehavior is not present in the Behavior, then add if (operationBehavior == null) { operationBehavior = new DataContractSerializerOperationBehavior(operation); operation.Behaviors.Add(operationBehavior); } //IMPORTANT: As 'operationBehavior' is a reference, changing anything here will automatically update the value in list, so no need to add this behavior to behaviorlist operationBehavior.MaxItemsInObjectGraph = 2147483647; } return proxy; } 

When I try to compile I get two errors:

Error 1 'Proxy<...>': cannot declare instance members in a static class

and

Error 3 The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)

What am I missing in order to use the ChannelFactory class?

EDIT:

I have changed ChannelFactory to ChannelFactory but now I receive the following error:

Error 1 'Proxy<...>': cannot declare instance members in a static class

4
  • msdn.microsoft.com/en-us/library/ms734681.aspx Commented Jun 30, 2016 at 2:36
  • Could you give an example on how it would look using the public virtual ChannelFactory<T> Proxy<T>(string address) method? Commented Jun 30, 2016 at 2:41
  • There are lots of example : msdn.microsoft.com/en-us/library/bb412178(v=vs.110).aspx and your T is just interface for data exchange. Commented Jun 30, 2016 at 2:42
  • I see that makes sense so looking at my config file instead of T I would use: IReportData? Commented Jun 30, 2016 at 2:45

1 Answer 1

2
Error 1 'Proxy<...>': cannot declare instance members in a static class 

Look at the class that this method is inside and make sure it's not static.

Error 3 The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?) 

When you see a definition for a generic class like ChannelFactory<T> or List<T>, T is just a placeholder for the actual type, like List<string> or List<DateTime>. From looking at the code above I'm guessing it's ChannelFactory<IReportData>.


Here's a really simple client. I used the sample service that gets created whenever you make a new WCF application project.

public class MyServiceClient : ClientBase<IService>, IService { public string GetData(int value) { return base.Channel.GetData(value); } public CompositeType GetDataUsingDataContract(CompositeType composite) { return base.Channel.GetDataUsingDataContract(composite); } } 

From the documentation for ChannelFactory:

The generic ChannelFactory class is used in advanced scenarios that require the creation of a channel factory that can be used to create more than one channel.

In other words, if you're just trying to create a client then you probably don't need to use ChannelFactory.


In practice, I use Castle Windsor WCF Integration Facility to create my WCF clients. That's only applicable if you're interested in using dependency injection and working with Castle Windsor. I highly recommend learning to work with it just because dependency injection is a useful practice. But then in addition to that you get the convenience of using it to create and dispose your clients.

The result is that your classes never "know" about the WCF service. They just know that they're using IReportData. They have no idea that the implementation of that interface is a WCF client. Behind the scenes Windsor is creating and disposing the client, and in most cases the only configuration is a one-line <endpoint> element in your app.config.

Here's the entry page for their documentation.

Sign up to request clarification or add additional context in comments.

5 Comments

I have changed it to ChannelFactory<IReportData> but now I'm getting this error: Error 1 'Proxy<...>': cannot declare instance members in a static class
Make sure the class isn't static. I'm working on an addition to the answer that might make it easier.
only static members in static class
I see that makes sense because when I added the service reference IReportData actually lights up so it is aware of the interface but currently it does not. I looked at the Castle Windsor and I think that will help me create the client to connect to the service, my last question is : Does Windsor allow me to configure the MaxQuotas? I'm returning a large xml so I just want to make sure that won't be an issue with Windsor.
Yes, you can configure all of the same options with windsor. It uses the same endpoint config element, or you csn do it in code.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.