Saturday, April 27, 2013

Project item '4294967294' does not represent a file.

Wow, that’s a pretty non-descriptive error message, isn’t it? And the funny thing is, that particular item number is always the same! What the heck is this?

This is an error message you can get in Visual Studio. I don't know if this is specific to SSRS report projects or not, but I suspect it is. I ran into the error when trying to open a solution with a .rptproj.

Googling finds all sorts of stuff about deleting a line out of the rptproj file and rebinding to source control (most mention Source Safe, but I use TFS and still had the issue). Also, this was in VS2005 (because we're using SSRS 2005 … and the reason for that is a story for another day).

It turns out, this guy had the answer all along and it didn't involve mucking about with the .rptproj file!

http://followtheheard.blogspot.com/2008/03/error-opening-reporting-services.html

The issue is caused because someone checked in their .rptproj.user file. That's the only thing wrong! The .user file is specific to a particular user and should never be checked in (I don't know why it was to begin with). The solution is easy ... check out the .user file and then delete it. I couldn't delete it from TFS (because other people had done the same thing and you can't delete a file from TFS if it has pending changes). But, you can just delete it from your own folder, then re-open your solution and all will be fixed!

Saturday, March 30, 2013

Code Snippets

Today I’m going to write about code snippets. Code Snippets have been in use since Visual Studio 2005. I knew about them then, but didn’t really have a need to create my own, so I eventually forgot about them until about 4 months ago, when I found I had a really, really, really good use for them!

But, let’s back up a bit … what is a code snippet? Surely you have taken advantage of them without realizing it. Think about loops: just type the word for and hit tab twice. Voila, the entire for loop is stubbed out for you to fill in the details:

for (int i = 0; i < length; i++)
{
    
}

Likewise, try foreach and hit tab twice. Here’s what you get:

foreach (var item in collection)
{
    
}

If you haven’t already discovered this feature, you’re in for a treat. Try it yourself right now, you’ll love it! The “for” and the “foreach” are called shortcuts. If you don’t know a shortcut, or can never remember the one you want or you simply want to explore, all you have to do is position your mouse in your code where you want to insert a code snippet, then right-click and choose “Insert Snippet …” and find what you’re looking for or something else that looks interesting.

Now for the good part … you can create your own code snippets to do simple “templates” (like those for loops above) or more complicated “templates'”. I had big chunks of semi-repetitive code; groups of methods that needed to be put into each new module written (a new module to interface with each different vendor product, so each bit of code would use different parameters in the methods).

I wrote a big long snippet for that use (and it works beautifully) and after that I was hooked on creating snippets! I regularly use 4 or 5 that I created in every new module I have to write. It speeds up my coding tremendously, not to mention gets rid of any possibilities for screwing up and leaving out something important.

First, here’s a link for future reference if you need to know more than I can tell you in this short blog:

http://msdn.microsoft.com/en-us/library/vstudio/ms165393(v=vs.100).aspx

Next, let me show you what the file looks like for those simple snippet examples I showed above. Let’s just do the “foreach” one. Here’s the entire foreach.snippet file … it’s just XML:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>foreach</Title>
            <Shortcut>foreach</Shortcut>
            <Description>Code snippet for foreach statement</Description>
            <Author>Microsoft Corporation</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
                <SnippetType>SurroundsWith</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>type</ID>
                    <ToolTip>Type of object in the collection to iterate through</ToolTip>
                    <Default>var</Default>
                </Literal>
                <Literal>
                    <ID>identifier</ID>
                    <ToolTip>Identifier that represents the element in the collection</ToolTip>
                    <Default>item</Default>
                </Literal>
                <Literal>
                    <ID>collection</ID>
                    <ToolTip>Name of collection or array to iterate through</ToolTip>
                    <Default>collection</Default>
                </Literal>
            </Declarations>
            <Code Language="csharp"><![CDATA[foreach ($type$ $identifier$ in $collection$)
    {
        $selected$ $end$
    }]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

So, how does this work? Notice the very last thing in the XML, this is the part that contains the code “template” that will become the snippet (all the stuff contained within the CDATA).

foreach ($type$ $identifier$ in $collection$)
{
    $selected$ $end$
}

All the things delimited by the “$” are what will get replaced in the IDE when you hit tab twice. The Declarations in the beginning of the XML describe what each of these literals should be, along with the defaults that are initially displayed in your IDE. The $selected$ and $end$ are special literals. Here’s what MSDN has to say about them:

Two reserved words are available for use in the text of the Code element: $end$ and $selected$. $end$ marks the location to place the cursor after the code snippet is inserted. $selected$ represents text selected in the document that is to be inserted into the snippet when it is invoked. For example, if you had:

$selected$ is a great color. I love $selected$.

and the word "Blue" was selected when you invoked the template, you would get:

Blue is a great color. I love Blue.

All other $ keywords are dynamically defined in the <Literal> and <Object> tags.

What they mean by “selected text” is when you highlight some text in your code, then right-click and choose “Surround With …” and then pick a snippet to use.

Here’s something I wrote to help out a guy on the MSDN forums (see the thread here, if you’re interested: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3198baaa-0250-49c6-bad5-f5242a2b5852). He wanted to have a static property that was set by calling a method … but, he didn’t want to have to run that method every time he used the property. And, he used these types of properties everywhere, so he didn’t want to have to type the same monotonous stuff over and over again. To me, it sounded like the perfect use for a code snippet.

Here’s the GetPropOnce.snippet I wrote for that:

<?xml version= "1.0" encoding="utf-8" ?>
<CodeSnippets xmlns = "http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format ="1.0.0">
    <Header >
        <Title>GetOnce Property</Title>
        <Description>Property that is only gotten once, checking backing variable for null</Description>
        <Shortcut>propgetonce</Shortcut>
    </Header>
    <Snippet>
        <Declarations>
            <Literal>
                <ID>type</ID>
                <Default>int</Default>
            </Literal>
            <Literal>
                <ID>PropertyName</ID>
                <Default>MyProperty</Default>
            </Literal>
            <Literal>
                <ID>MethodName</ID>
                <Default>DoSomething</Default>
            </Literal>
            <Literal>
                <ID>DefaultValue</ID>
                <Default>DefaultForNull</Default>
            </Literal>
        </Declarations>
        <Code Language="CSharp">
            <![CDATA[
                private $type$? m_$PropertyName$ = null;
                public $type$ $PropertyName$
                {
                    get
                    {
                        if (m_$PropertyName$ == null)
                        {
                            m_$PropertyName$ = $MethodName$();
                        }
                        return m_$PropertyName$ ?? $DefaultValue$;
                    }
                }
             ]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

A lot of stuff, but still pretty easy. The code template part of it is pretty straightforward:

private $type$? m_$PropertyName$ = null;
public $type$ $PropertyName$
{
    get
    {
        if (m_$PropertyName$ == null)
        {
            m_$PropertyName$ = $MethodName$();
        }
        return m_$PropertyName$ ?? $DefaultValue$;
    }
}

Cool, huh? But, it was time-consuming to write all those literals and everything in XML. Now, I just wrote this last week (which is what made me think I should write a blog post about it), but I thought at the time that there had to be an easier way to write the .snippet file. I didn’t get around to looking for anything to make it easier until I started researching for writing this blog post. I found a decent Snippet editor/designer on CodePlex:

http://snippetdesigner.codeplex.com/

This designer is a plug-in for Visual Studio (download it, double-click what you downloaded, and it adds it to Visual Studio for you). Basically, with this plug-in you only have to write the template (without all the $ delimiters), and indicate which parts of that template should be the literals and it does a lot of the grunt work for you. And, what’s even better is you can use existing code in the IDE (or write some new code just for this purpose) … just select the code, right-click and choose “Export As Snippet” and you’re in the designer with your selected code all set to make it into a template. Couldn’t be easier … I wish I had discovered this plug-in a few months back when I was writing some heavy-duty snippets!

Enjoy!

Saturday, January 19, 2013

Watch Out For DateTime.TryParse()

You’ve heard all kinds of good things about the various .TryParse() methods, and rightly so. They’re a good way to convert an object to the appropriate data type, such as int, long, decimal, DateTime, etc., without having to worry about the conversion throwing an exception if the object cannot be converted to the appropriate data type. For example, you could get an exception if you simply tried to cast the object:

int x = (int)MyObject; // could throw an exception

or if you used the Convert methods:

int x = Convert.ToInt32(MyObject); // could throw an exception

But, the .TryParse() methods avoid all that and simply do the conversion if possible. If the string can be converted to the data type, the value is put into the out parameter and the method returns true. If it cannot be converted, a default value is put into the out parameter and the method returns false.

int x;

// You can choose to check the bool value that's returned
if (int.TryParse(MyObject.ToString(), out x))
{
    // We have a valid value, do something
}

// Or don't bother checking the boolean, if you're OK with the default
// if MyObject cannot be converted. In this case, int, the default is 0.
int.TryParse(MyObject.ToString(), out x);

Now, let me say that the DateTime.TryParse() works fine too, but there is one gotcha to look out for. If the DateTime object that you wish to Parse comes from a database and you need the entire precision of that value, then you can’t use .TryParse(). In other words, more precision than down to the second. Let’s look at a DateTime value that I retrieve from a SQL Server database table, that was put into a column via GETDATE() in a SQL Stored Procedure:  09:31:45.333  Note that this is a bit more precise than down to 45 seconds. There’s that decimal value of .333 after it. Why would you care about that?

Here’s the scenario that bit me: Rows are entered in a database table every time an activity occurs, which could be as often as 30 seconds. Periodically, I need to retrieve the data for the most recent activity. So, I use “SELECT MAX(StatusTime) FROM etc...”  that returns the most recent DateTime from the above mentioned table, which I retrieve by running command.ExecuteScalar(). The only datatype that .ExecuteScalar() returns is an object. In order to then make use of this newly retrieved date, I need to convert it to a DateTime variable. I had been so enamored of using TryParse() for this type of  thing, that I just went ahead and used it here too.

command.CommandText = "SELECT MAX(StatusDate) FROM MyTable GROUP BY ActivityID";
DateTime LastStatusDate;
DateTime.TryParse(command.ExecuteScalar().ToString(), out LastStatusDate);

The only time that the value returned from the query will be DBNull is at the very start, when the app is first used and the database contains no data or when it’s the first time using that particular ActivityID. In either case, I was ok with the default value, which is DateTime.MinValue.

So, in my testing, when retrieving activity within a date range, I never got the very last set of activity records. I would get everything before 09:31:45.000, but I knew that there was also activity “posted” at 09:31:45.333 which wasn’t being retrieved.

The culprit? The .ToString()!! The time portion of my date went from being 09:31:45.333 in the database, to being 09:31:45 in my LastStatusDate variable because the .ToString() doesn’t “recognize” the decimal portion of the time. Consequently, any activity that had the time of 09:31:45.333 was not being retrieved!!

The obvious solution to this dilemma is to check that the object returned from the .ExecuteScalar() is of the DateTime datatype and then cast the object to my LastStatusDate variable. I could see that potentially I may want to use this functionality more than just this one place, so I decided to write an extension method for object data types to handle this. I actually wrote two of them and they work perfectly!

// Extension methods for Dates
public static DateTime ToDate(this object o)
{
    if (o is DateTime)
        return (DateTime)o;
    else
        return DateTime.MinValue;
}
public static bool TryParseDate(this object o, out DateTime date)
{
    if (o is DateTime)
    {
        date = (DateTime)o;
        return true;
    }
    else
    {
        date = DateTime.MinValue;
        return false;
    }
}

The reason I wrote two different extension methods is that sometimes you need to test the boolean return value of a TryParse() kind of method and sometimes you don’t. Here’s how to use both extension methods:

DateTime LastStatusDate;
if (command.ExecuteScalar().TryParseDate(out LastStatusDate))
{
    // do something with the LastStatusDate variable
}

Or, if you don’t  wish to check the boolean, such as maybe adding a date to a List<DateTime>:

MyDateList.Add(command.ExecuteScalar().ToDate());

Or just setting the variable:

LastStatusDate = command.ExecuteScalar().ToDate();

Obviously these two extension methods can be used with any type of object (for example, a DataRow column in a DataTable), I just showed it here using the same object (the result returned from the ExecuteScaler() method) for consistency in my example.

They are pretty handy extension methods … I highly recommend adding them to your bag of tricks!

Monday, December 31, 2012

Passing Data Between Forms Redux

Almost exactly two years ago, I published the Passing Data Between Forms post. I have had numerous questions and comments about that post and now I’ve decided that it deserves an additional example.

In that post, I had an example (the 3rd one) that utilized Interfaces. In the example, we had a MainForm that passed a DataSet to Form1. Form1 then allowed the user to make some changes to the data in that DataSet and then we wanted to have MainForm automatically reflect those changes ... even while the user was still working in Form1. An interface worked well for that scenario. At the time, I wanted to keep the post simple so as not to confuse beginners. But, I really need to expand on that example and show how to accomplish this task using delegates/events.

So, without further ado (pun intended), here it is:

First, let's take a look at Form1. Minimally, you can implement this whole thing with a simple event, which uses standard EventArgs, as follows:

public class Form1 : Form
{
    public event EventHandler DataChanged;
    private CustomerDataSet oData;

    public Form1(CustomerDataSet dsCust)
    {
        this.oData = dsCust;
    }
    public void DoStuff()
    {
        // code to do stuff with this.oData
        // ...
        // and then fire the event if anyone has subscribed
        this.OnDataChanged(new EventArgs());
    }
    private void OnDataChanged(EventArgs e)
    {
        if (this.DataChanged != null)
            this.DataChanged(this, e);
    }
}

Then, the MainForm looks like this:

public class MainForm : Form
{
    private CustomerDataSet dsCustomer;

    // ...

    // then code elsewhere to instantiate and fill your data
    this.dsCustomer = new CustomerDataSet();
    // plus maybe other code to fill the dataset


    // ...

    // code to instantiate Form1, pass it the DataSet, handle the event
    Form1 oForm = new Form1(this.dsCustomer);
    oForm.DataChanged += new EventHandler(DataChanged);
    oForm.Show();

    public void DataChanged(object sender, EventArgs e)
    {
        // code here to do stuff with this.dsCustomer
    }
}

In this particular case, we don't really need EventArgs. Because we passed the DataSet into Form1 to begin with, we already know everything we need to know, namely the data that has changed will be the same DataSet that we passed into Form1. So, since we don’t need any EventArgs, we could create a custom delegate to use as our event handler. We will change our two forms like this:

Form1:

public class Form1 : Form
{
    public delegate void DataChangedEventHandler();
    public DataChangedEventHandler DataChanged;
    private CustomerDataSet oData;

    public Form1(CustomerDataSet dsCust)
    {
        this.oData = dsCust;
    }
    public void DoStuff()
    {
        // code to do stuff with this.oData
        // ...
        // and then fire the event if anyone has subscribed
        this.OnDataChanged();
    }
    private void OnDataChanged()
    {
        if (this.DataChanged != null)
            this.DataChanged();
    }
}

The only difference in MainForm is that the event handler doesn't need the usual parameters (object sender, EventArgs e), so change the DataChanged event handler to look like this:

// code to instantiate Form1, pass it the DataSet, handle the event
Form1 oForm = new Form1(this.dsCustomer);
oForm.DataChanged += new Form1.DataChangedEventHandler(DataChanged);
oForm.Show();

public void DataChanged()
{
    // code here to do stuff with this.dsCustomer
}

Another way of handling the event in the MainForm is to not even bother with the above DataChanged() method and use an anonymous delegate instead, so you could change the MainForm code to look like this:

// code to instantiate Form1, pass it the DataSet, handle the event
Form1 oForm = new Form1(this.dsCustomer);
oForm.DataChanged += delegate
{ 
    // code here to do stuff with this.dsCustomer
};
oForm.Show();

There are other things you can do when creating your own delegates and/or events and, in fact, I have a written a blog post about a DataAccess class that does some interesting things with anonymous delegates: DataAccess - Part III.

However, expanding on ideas for delegates and/or events is beyond the scope of this simple post. Perhaps in the future I’ll write something more extensive, but in the meantime, you can always start off with an MSDN article such as this one: Handling And Raising Events

Sunday, December 16, 2012

ComboBox Gotchas

This is pretty well-known for experienced Windows Forms developers, but I still see the problem frequently asked about on the forums. Typically, the questions will be something like:

  1. “Every time I make a different selection from my ComboBox, the row in my grid changes.”
  2. “I have two ComboBoxes on my Form, but they’re in sync. Every time a selection is made in  one, the selection changes in the other.”

So, what is it that they’re doing wrong? Well, the DataSource of a ComboBox cannot be in use by any other databound control on the Form … unless, of course, your intention is to use the ComboBox for navigation … but then, you wouldn’t be asking these questions!

It doesn’t matter if you are using an actual DataTable for your Combo’s DataSource, or if you’re using a BindingSource, the bottom line is that you cannot use the same object to databind other controls. How about a few illustrative examples, first with DataTable and then with BindingSource? In my scenario, I’ll use 3 controls, a DataGridview, a TextBox and a ComboBox. I want the DataGridView and the TextBox to be in sync. When I move through the grid, the value in the TextBox changes accordingly. The ComboBox, on the other hand, should behave independently.

Using DataTables as DataSource

First, let’s set up the databinding for the grid and textbox:

this.dataGridView1.DataSource = this.dtMyTable;
this.txtLastName.DataBindings.Add("Text", this.dtMyTable, "Code");

And now, in order to see how NOT TO bind the ComboBox, try the following code and notice what happens! 

// As we now know, by setting the ComboBox.DataSource to a DataTable that's already bound elsewhere
// moving through the Combo also affects the bound textbox and the grid. This is BAD CODE!!
this.cboDescription.DisplayMember = "Description";
this.cboDescription.DataSource = this.dtMyTable;

Well, ok, it’s bad. What can we do instead? We have two choices:

// Setting the DataSource to a DataView of the same DataTable works just fine
DataView dv = new DataView(this.dtMyTable);
this.cboDescription.DisplayMember = "Description";
this.cboDescription.DataSource = dv;

-OR-

// We could use a Copy of the original DataTable
this.cboDescription.DisplayMember = "Description";
this.cboDescription.DataSource = this.dtMyTable.Copy();

Either way gives you the correct results: when the user changes the selection in the Combo,  nothing at all happens to the grid or textbox.

Using BindingSources as DataSource

Getting the same results using BindingSources is similar. First, set up the binding of the grid and textbox:

BindingSource bs = new BindingSource();
bs.DataSource = this.dtMyTable;
this.txtLastName.DataBindings.Add("Text", bs, "Code");
this.dataGridView1.DataSource = bs;

And again, in order to see how NOT TO bind the ComboBox, try the following code and notice what happens!

// Now the Combo DataSource: As expected, using the same BindingSource doesn't work. BAD CODE
this.cboDescription.DisplayMember = "Description";
this.cboDescription.DataSource = bs;

And what can we do instead?

// A new BindingSource works fine
this.cboDescription.DataSource = new BindingSource(this.dtMyTables, null);

And here’s an interesting one to try:

// A new BindingSource based on the old BindingSource
// Yep! This one works too!
this.cboDescription.DataSource = new BindingSource(bs, null);

Binding the ComboBox

Now, there’s one more thing I’d like to explore. What do you code if you need to have the SelectedValue of the ComboBox be tied to the what’s being displayed in the grid (or perhaps elsewhere, say maybe a label). Previously, we have only set the Combo’s DataSource, but this doesn’t do anything with whatever the user has selected from the Combo. So now we want to databind it, as we’ve databound the grid and the textbox. Let’s say we have another control, a label, and we want it to reflect the chosen Description in the ComboBox. We’d need to bind the label and Combo to the same thing.

// Using the DataTable:
this.lblDescription.DataBindings.Add("Text", this.dtMyTable, "Description");
this.cboDescription.DataBindings.Add("SelectedValue", this.dtMyTable, "Description");

// Or, using the BindingSource instead:
this.lblDescription.DataBindings.Add("Text", bs, "Description");
this.cboDescription.DataBindings.Add("SelectedValue", bs, "Description");

Try either methodology. Select an item from the Combo and notice that the label changes to reflect that selection. Then, move between rows in the grid. You should notice the label changes then too. When on a different row in the grid, change the selection of the Combo again. When moving back and forth between rows in the grid, notice that the ones you changed with the Combo selection remain at that new value.

Sunday, October 28, 2012

Crowd Funding

Some of you may have heard of “Crowd Funding” or “Cyber Begging” or any of the other newest buzz words involving, basically, raising money online: sometimes for a good cause, sometimes to help start a business, sometimes for no reason except that you need money. We’ve all been there at some point in our life …

I’m unfortunately in that situation right now. Little to no income for 3 years now, while we try to start up a new business … it doesn’t take long before the savings account gets depleted! But, we've got a great product and one customer who loves it! It's only a matter of time before we get more customers. In the meantime, we need more cash. Here's our business website: Geneva Systems Group

Anyway, I’ve got a PayPal “Donate” button here on my blog site, that I’ve had since I started this blog. It sure would be nice if some of my many readers would take the time to just click that button. You don't even need a Paypal account to donate (Paypal will accept credit card donations although your credit card company may charge a fee).

I'm thinking of putting another PayPal button here, specfically for this funding campaign, but until I do please use the only one on the page.

Every little bit helps and I’d sure appreciate it!!!

XAML Intellisense

I’ve done a little here and there with WPF over the past few years. Nothing of production quality, but still a bit more than just “playing with it”. One of the things that bugged the hell out of me was that I couldn’t figure out how to get Intellisense to kick in while working with the XAML (I rarely use the designer). Lately I’ve been getting back into WPF a bit more deeply and when you start designing more complicated UI, you really need to have XAML Intellisense, otherwise you have to keep looking stuff up!

So, I Googled around for an answer and finally found something after many search attempts. And wow, it’s soooooo simple! Here’s where I found the answer, and I want to sincerely thank Fabrice for posting this: http://weblogs.asp.net/fmarguerie/archive/2009/01/29/life-changer-xaml-tip-for-visual-studio.aspx

Basically, what Fabrice says is to use the Source Code Editor rather than the XML editor. That’s it in a nutshell and it’s one of those forehead-slapping, duh, why-didn’t-I-think-of-that kind of things!

You can read Fabrice’s blog, but here are his 6 easy steps:

  1. Right-click on a XAML file in the Solution Explorer
  2. Select "Open With..."
  3. Select "Source Code (Text) Editor"
  4. Click on "Set as Default"
  5. Click OK
  6. You're done!

Sunday, September 02, 2012

A Generic WCF Proxy Class

A couple of years ago, when I first started using WCF, it seemed like a real pain in the you-know-what to add Service References to my app in order to consume WCF Services. I wanted a base Proxy class that I could extend to be used for any kind of ServiceContract. The key to writing this class was the use of generics Here’s what I came up with, after much trial and error (be sure you have using System.ServiceModel and using System.ServiceModel.Channels):

public abstract class ProxyBase<T> where T : class
{
    #region Declarations
    public ChannelFactory<T> Factory = null;
    public T proxy { get; set; }
    public string EndpointName { get; set; }
    private string m_Certificate;
    public string Certificate
    {
        get { return this.m_Certificate; }
        set
        {
            try
            {
                this.m_Certificate = value;
                if (this.m_Certificate.IsNotNullOrEmpty() && Factory != null)
                {
                    EndpointIdentity Identity = EndpointIdentity.CreateDnsIdentity(this.m_Certificate);
                    if (Identity == null)
                        Console.WriteLine("Identity Is Null");
                    else
                    {
                        Uri AddressUri = Factory.Endpoint.Address.Uri;
                        Factory.Endpoint.Address = new EndpointAddress(AddressUri, Identity);

                        // not sure, but probably have to remove old EventHandler before recreating the 
                        // proxy and recreating the Channel.
                        ((ICommunicationObject)proxy).Faulted -= new EventHandler(ProxyBase_Faulted);
                        proxy = Factory.CreateChannel();
                        ((ICommunicationObject)proxy).Faulted += new EventHandler(ProxyBase_Faulted);
                    }
                }
            }
            catch (Exception ex)
            {
                Factory = null;
                proxy = null;
            }
        }
    }
    #endregion

    #region Constructors
    public ProxyBase() { }
    public ProxyBase(string endpoint)
    {
        // not the best error-handling, but good enough for now
        // TODO - make error-handling better
        //        Already handling faulted channels, but now need to do something for bad addresses?
        //        Because I *think* a bad address will cause an exception in the creation of the Factory.
        try
        {
            this.EndpointName = endpoint;
            Factory = new ChannelFactory<T>(endpoint);
            proxy = Factory.CreateChannel();
            ((ICommunicationObject)proxy).Faulted += new EventHandler(ProxyBase_Faulted);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error in Proxy for {0}, Endpoint: {1}\r\n{2)", typeof(T).Name, endpoint, ex.Message);
            Factory = null;
            proxy = null;
        }
    }
    public ProxyBase(string endpoint, string address)
    {
        // not the best error-handling, but good enough for now
        // TODO - make error-handling better
        //        Already handling faulted channels, but now need to do something for bad addresses?
        //        Because I *think* a bad address will cause an exception in the creation of the Factory.
        try
        {
            this.EndpointName = endpoint;
            Factory = new ChannelFactory<T>(endpoint);
            Factory.Endpoint.Address = new EndpointAddress(address);
            proxy = Factory.CreateChannel();
            ((ICommunicationObject)proxy).Faulted += new EventHandler(ProxyBase_Faulted);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Proxy for {0}, Endpoint: {1}, Address: {2}\r\n{3}", typeof(T).Name, endpoint, address, ex.Message);
            Factory = null;
            proxy = null;
        }
    }
    #endregion

    #region Methods
    public void Close()
    {
        if (proxy != null)
            ((IChannel)proxy).Close();
        if (Factory != null)
            Factory.Close();
    }
    #endregion

    #region Events
    private void ProxyBase_Faulted(object sender, EventArgs e)
    {
        Console.WriteLine("Proxy for {0}\r\n{1}", typeof(T).Name, ((IChannel)proxy).State.ToString());
        ((ICommunicationObject)sender).Abort();
        proxy = Factory.CreateChannel();
    }
    #endregion
}

Seems pretty simple. Notice that it’s an abstract class. You must sub-class it in order to use it. OK, so how do we construct the sub-class? Very simple also. First, you must have a few Interfaces defined, as you would normally have for any WCF service. Here is what I’m going to use for my example:

[ServiceContract(Namespace = "http://MyCompany")]
public interface IMessageService
{
    [OperationContract(IsOneWay = true)]
    void ProcessMessage(IMessage message);
}

[ServiceContract(Namespace = "http://MyCompany")]
public interface ISynchronousMessageService
{
    [OperationContract]
    bool ProcessMessage(IMessage message);
}

public interface IMessage
{
    string MessageToSend { get; set; }
    string MessageReceived { get; set; }
}
public class MyMessage : IMessage
{
    public string MessageToSend { get; set; }
    public string MessageReceived { get; set; }
}

All WCF Services need to have a ServiceContract and OperationContract, so there they are. I’ve also got an interface defined for the Messages I’m going to send, plus a MyMessage class that implements that IMessage interface.

Next, here is what my sub-classed Proxies might look like:

public class SynchronousProxy : ProxyBase<ISynchronousMessageService>, ISynchronousMessageService, IDisposable
{
    #region Constructors
    public SynchronousProxy(string endpoint) : base(endpoint) { }
    public SynchronousProxy(string endpoint, string address) : base(endpoint, address) { }
    #endregion

    #region Methods
    public virtual bool ProcessMessage(IMessage message)
    {
        try
        {
            if (proxy != null)
                return proxy.ProcessMessage(message);
            else
                return false;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception, ProcessMessage\r\n{0}", ex.Message);
            return false;
        }
    }
    public void Dispose()
    {
        this.Close();
    }
    #endregion
}
public class Proxy : ProxyBase<IMessageService>, IMessageService, IDisposable
{
    #region Constructors
    public Proxy(string endpoint) : base(endpoint) { }
    public Proxy(string endpoint, string address) : base(endpoint, address) { }
    #endregion

    #region Methods
    public virtual void ProcessMessage(IMessage message)
    {
        try
        {
            if (proxy != null)
                proxy.ProcessMessage(message);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception, ProcessMessage\r\n{0}", ex.Message);
        }
    }
    public void Dispose()
    {
        this.Close();
    }
    #endregion
}

And now, how do I actually use these proxy classes? You’d have the usual WCF stuff defined in the .config in the endpoint in the systemServiceModel tags:

  <system.serviceModel>
    <client>
      <endpoint name="MyEndpoint"
          address="net.tcp://MyComputer:666/MyMessageService"
          binding="netTcpBinding" bindingConfiguration="netTcpConfig"
          contract="MyApp.IMessageService"/>
    </client>
  </system.serviceModel>

And then in your code, you’d call the WCF service like this:

using (Proxy proxy = new Proxy("MyEndpoint"))
{
    MyMessage message = new MyMessage();
    message.MessageToSend = "MyTestMessage";
    proxy.ProcessMessage(message);
}

Wow, that’s pretty easy, isn’t it? No need to add ServiceReferences or anything like that. All you need to know are the Interfaces that the Services use and you’re good to go!