How do I get started using NetTcpBinding and Windows Forms / WPF?

How do I get started using NetTcpBinding and Windows Forms / WPF?

Old forum URL: forums.lhotka.net/forums/t/7216.aspx


robdal posted on Thursday, July 02, 2009

Hi,
I've never developed a project using CSLA and I'm just getting started. Since my project will work on an intranet I'll be using nettcpbinding and the server will be a WPF application. I looked if I could find a sample to get started in that direction but everything I found has to do with the web. I just finished watching the full series of video tutorials on CSLA for Silverlight and bought the book, and I've been able to reproduce the simplest Silverlight samples. Nonetheless I can't figure out how to get started in a different scenario.
Any hint will be greatly appreciated
Roberto Dalmonte

RockfordLhotka replied on Thursday, July 02, 2009

If I were you, I'd use HTTP binding first, to get an understanding of CSLA .NET itself and how to build and use business objects.

Using NetTcpBinding is not a CSLA thing, it is a WCF thing, but it brings complexity all by itself.

You can't host TCP in IIS (or can you in IIS 7?), so you have to create your own custom Windows service and set it up to host WCF using the TCP binding. That's just a few lines of code to get a basic, non-reliable service running. But if you want any sort of reliability you'll need to at least add logging to the system event log, and very possibly create your own AppDomain to host the WCF service so you have the possibility of doing a restart if you detect a runaway condition.

Or you can use WAS (Windows Activation Service) if your server is Win2k8 - and that is probably a much smarter idea, since Microsoft already does a lot of this reliability work for you in that case.

Using the TCP binding on the client is pretty easy. Once you have your service running, just use the correct WCF configuration in the client config file so WCF knows to use the NetTcpBinding to talk to your service at the correct URL.

You should get Michelle's Learning WCF book.

robdal replied on Thursday, July 02, 2009

Thanks for answering.
In my project I'm using WCF (Miguel Castro way, as seen on DNRTV episode "Extreme WCF"). I LOVE IT. I LOVE IT. I LOVE IT.
I use 5 different assemblies:
1) the contract assembly

public interface IArchive
{
[OperationContract]
IEnumerable GetSpecificData(String query, Int32 id);
}

2) the service assembly
public class ArchiveService : IArchive
{
IEnumerable IArchive.GetSpecificData(String query, Int32 id)
{
//Actual implementation to get data
}
}

3) the server assembly that hosts the service
public class Server
{
private void StartService()
{
String baseAddress = "net.tcp://localhost:8002/ArchiveEndpoint";
NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
XmlDictionaryReaderQuotas quota = new XmlDictionaryReaderQuotas();
quota.MaxStringContentLength = 1000000;
quota.MaxArrayLength = 2147483647;
binding.MaxBufferSize = 2147483647;
binding.MaxReceivedMessageSize = 2147483647;
binding.ReaderQuotas = quota;
binding.TransferMode = TransferMode.Streamed;
ServiceHost serviceHost = new ServiceHost(typeof(ArchiveService));
serviceHost.AddServiceEndpoint(typeof(IArchive), binding, baseAddress);
serviceHost.Opened += new EventHandler(OnServiceHostOpened);
serviceHost.Open();
}
}

4) the proxy assembly
public class CustomProxy
{
internal IEnumerable GetSpecificData(String query, Int32 id)
{
IArchive proxy = new ChannelFactory(binding, ea).CreateChannel();
using (proxy as IDisposable)
{
return proxy.GetSpecificData(query, id);
}
}
}

5) The client assembly

public class Client
{
internal static IEnumerable GetSpecificData(string query, Int32 id)
{
CustomProxy proxy = new CustomProxy();
return proxy.GetSpecificData(query, id);
}
}

My application it's a dental software that runs in a local netword inside the dental office, and I believe NetTcpBinding is faster than HttpBinding.
It's a couple of years I'm trying to use CSLA (I bought all your books in the last 5 years) but I fail systematically.

Is there a way to combine WCF and NetTcpBinding and CSLA?
I'm afraid you answered me already.
can I bypass your DATAPORTAL (if I understand correctly) and use your business classes with validation, authorization and so on?
I would really love to use your CSLA, you made an incredible job.
Best regards
Roberto Dalmonte

RockfordLhotka replied on Thursday, July 02, 2009

You absolutely can use the data portal with NetTcpBinding. Any synchronous WCF binding will work with the data portal. You already have the code you need - just set your service to use the pre-existing WcfHost interface/service types in Csla.Server.Hosts and you should be good to go.

Look in Chapter 15 of the Expert 2008 Business Objects book to get a deeper understanding of the data portal and how it integrates with WCF.

You can also use the data portal in local mode (client-only) and then in your DataPortal_XYZ methods or object factories you can call your custom services however you'd like. If you do this then you lose the n-tier features of CSLA .NET, but you keep all the client-side features like data binding, etc.

robdal replied on Thursday, July 02, 2009

Following your suggestion I created a service implementing the Csla.Server.Hosts.IWcfPortal interface


public class CustomService : Csla.Server.Hosts.IWcfPortal
{
#region IWcfPortal Members

public WcfResponse Create(CreateRequest request)
{
DataPortal portal = new DataPortal();
object result;
try
{
result = portal.Create(request.ObjectType, request.Criteria, request.Context);
}
catch (Exception ex)
{
result = ex;
}
return new WcfResponse(result);
}

}


Then I need a host for the service:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
StartService();
}

private void StartService()
{
String baseAddress = "net.tcp://localhost:8002/CustomServiceEndpoint";
NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
XmlDictionaryReaderQuotas quota = new XmlDictionaryReaderQuotas();
quota.MaxStringContentLength = 1000000;
quota.MaxArrayLength = 2147483647;
binding.MaxBufferSize = 2147483647;
binding.MaxReceivedMessageSize = 2147483647;
binding.ReaderQuotas = quota;
binding.TransferMode = TransferMode.Streamed;
ServiceHost serviceHost = new ServiceHost(typeof(CustomService));
serviceHost.AddServiceEndpoint(typeof(IWcfPortal), binding, baseAddress);
serviceHost.Open();
this.Title = "Service Started";
}
}

a client proxy
public class ClientProxy
{
private NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
private XmlDictionaryReaderQuotas quota = new XmlDictionaryReaderQuotas();
private EndpointAddress ea;

internal ClientProxy()
{
//String server = RunSettings.Instance.ProgramSettings.ServerName;
string server = "localhost";
ea = new EndpointAddress(String.Format("net.tcp://{0}:8002/CustomServiceEndpoint", server));
quota.MaxStringContentLength = 1000000;
quota.MaxArrayLength = 2147483647;
binding.MaxReceivedMessageSize = 9000000;
binding.MaxBufferSize = 2147483647;
binding.ReaderQuotas = quota;
binding.TransferMode = TransferMode.Streamed;
}
internal DataPortalResult Create(Type oType, object criteria, DataPortalContext context)
{
IDataPortalProxy proxy = new ChannelFactory(binding, ea).CreateChannel();
using (proxy as IDisposable)
{
return proxy.Create(oType, criteria, context);
}
}
}

Finally I need a
business.client assembly
business.server assembly
dataaccess assembly

Can you confirm I'm on the right track, or otherwise give me some other hints?
Thank you

Copyright (c) Marimer LLC