Needing to be able to clone an object is a common requirement when working in .NET, since simply assigning an object instance to a new variable name just adds a reference pointer to the existing object and sometimes you need to be able to create a new instance that is an exact copy of the existing one.

For many of the existing classes in .NET, the clone method is available for just this purpose, but for custom classes you have written yourself you will need to implement the ICloneable interface (or just write your own clone method). For deep cloning, where you need to have all objects, including child objects, to be cloned rather than just assigning reference pointers to existing objects, this can be a little tricky. One method is to serialize the class into a memory stream and deserialize it to a new object, but the drawback here is that you can only clone classes that are binary-serializable. My classes are mostly XML serializable, so I wanted to use a different approach.

A search on the web brought up various samples of code to do deep cloning using reflection and recursion, but it took a little work and debugging on my part to get this approach to work correctly.

The first step was to create a base class that implements the ICloneable interface and uses reflection to clone the object, along with recursion for deep cloning child objects. I got a head start on this from a code sample I found perusing The Code Project (http://www.codeproject.com), so props go to Renfield78 at the code project for his post that got me started on this. Anyway, to make a long story short, with a little work and some debugging I was able to create base class in VB.NET that deep cloned object classes that inherit from it.

This code worked fine until it ran into properties based on Dictionary and/or List classes. Since I use these two generic collection classes frequently, I wrote two classes that inherited from these that implemented the ICloneable interface as well, after which I was able to clone a fairly deep class-hiearchy successfully.

The cloneable dictionary class (in simplified form) looks like this:


Imports System.Reflection

Public Class CloneableDictionary(Of T)
Inherits Dictionary(Of T)
Implements System.ICloneable

Public Function Clone() As Object Implements System.ICloneable.Clone
Dim NewDictionary As New CloneableDictionary(Of T)

If Me.Count > 0 Then
Dim ICloneType As Type = Me(0).GetType.GetInterface("ICloneable", True)
If Not (ICloneType Is Nothing) Then
For Each Value As T In Me
NewDictionary.Add(CType(Value, ICloneable).Clone)
Next
Else
Dim MethodsList() As MethodInfo = Me(0).GetType.GetMethods
For Each Value As T In Me
NewDictionary.Add(Value)
Next
End If
Return NewDictionary
Else
Return NewDictionary
End If
End Function

End Class


The cloneable list class is likewise pretty simple:


Imports System.Reflection

Public Class CloneableList(Of T)
Inherits List(Of T)
Implements System.ICloneable

Public Function Clone() As Object Implements System.ICloneable.Clone
Dim NewList As New CloneableList(Of T)
If Me.Count > 0 Then
Dim ICloneType As Type = Me(0).GetType.GetInterface("ICloneable", True)
If Not (ICloneType Is Nothing) Then
For Each Value As T In Me
NewList.Add(CType(Value, ICloneable).Clone)
Next
Else
Dim MethodsList() As MethodInfo = Me(0).GetType.GetMethods
For Each Value As T In Me
NewList.Add(Value)
Next
End If
Return NewList
Else
Return NewList
End If
End Function

End Class

Hopefully the above should be pretty self-explanatory. So long as you inherit from or use these classes in place of the base classes and the collections contain objects that implement the ICloneable interface (as shown below), these can be used with a deep cloning base class.

The base class for all your other object classes will then need to look something like this:


Imports System.Reflection

Public MustInherit Class CloneableObject
Implements System.ICloneable

Private Function Clone(ByVal vObj As Object)
If Not vObj Is Nothing Then
If vObj.GetType.IsValueType OrElse vObj.GetType Is Type.GetType("System.String") Then
Return vObj
Else
Dim newObject As Object = Activator.CreateInstance(vObj.GetType)
If Not newObject.GetType.GetInterface("IEnumerable", True) Is Nothing AndAlso Not newObject.GetType.GetInterface("ICloneable", True) Is Nothing Then
'This is a cloneable enumeration object so just clone it
newObject = CType(vObj, ICloneable).Clone
Return newObject
Else
For Each Item As PropertyInfo In newObject.GetType.GetProperties
'If a property has the ICloneable interface, then call the interface clone method
If Not (Item.PropertyType.GetInterface("ICloneable") Is Nothing) Then
If Item.CanWrite Then
Dim IClone As ICloneable = CType(Item.GetValue(vObj, Nothing), ICloneable)
Item.SetValue(newObject, IClone.Clone, Nothing)
End If
Else
'Otherwise just set the value
If Item.CanWrite Then
Item.SetValue(newObject, Clone(Item.GetValue(vObj, Nothing)), Nothing)
End If
End If
Next
Return newObject
End If
End If
Else
Return Nothing
End If
End Function

Public Function Clone() As Object Implements System.ICloneable.Clone
Return Clone(Me)
End Function

End Class


Assuming all of your custom classes derive from the above and all properties that are based on dictionary or list objects use the appropriate ICloneable implementation (as show in the first two code samples), these three classes in conjunction should provide most of your needs in being able to deep clone your own custom classes.
11

View comments

  1. Anonymous10:51 PM

    Good for people to know.

    ReplyDelete
  2. Anonymous7:25 AM

    Any tips on how to integrate cloneable list class inside the base class?

    ReplyDelete
  3. To integrate the cloneable list or dictionary classes inside the base class, first create your own list or dictionary class that inherits from the cloneable list or dictionary classes. Then create your main class and have that inherit from the base cloneable class. You can then add your inherited list or dictionary as a member of this main class, and when you clone the main class it should be able to clone the dictionary or list member also.

    ReplyDelete
  4. Anonymous1:04 AM

    Thanks for your quick response.

    It now works :)

    I sent you an email with som more questions including a code sample.

    ReplyDelete
  5. Anonymous7:10 AM

    One correction to my comment. You don't have to inherit from the list or dictionary classes, you can just create your list or dictionary object directly from these classes and then add them to the main base class as members, at which point the base class clone method should work properly.

    ReplyDelete
  6. (NOTE: Thanks to Kay for this comment. This was emailed to me and I decided it would be good to post here. If you need to use an inherited class of the CloneableList class rather than instantiating directly from it, this looks like a good solution.)

    Kay's Comment:

    I have got it to work now, but I had to do some tweaking.

    My code:

    public class MyObjectList<T> : CloneableList<T>
    {
    public override object Clone()
    {
    MyObjectList<T> NewList = new MyObjectList<T>(); // CloneableList<T> NewList = new CloneableList<T>();
    if (this.Count > 0)
    {
    Type ICloneType = this.GetType().GetInterface("ICloneable", true);
    if ((ICloneType != null))
    {
    foreach (T Value in this)
    {
    NewList.Add((T)((ICloneable)Value).Clone());
    }
    }
    else
    {
    foreach (T Value in this)
    {
    NewList.Add(Value);
    }
    }
    return NewList;
    }
    return NewList;
    }
    }

    I had to set "your" CloneableList class Clone method to virtual so I could override it because it returned a list of type CloneableList which caused an error since I need the returned list to be of type MyObjectList.

    ReplyDelete
  7. Your cloneable dictionary code is the same as the cloneable list code.

    ReplyDelete
  8. Anonymous5:21 AM

    Yes, the dictionary code does not compile as is.

    I don't need that so will use the other two.

    Thanks!! :-)

    ReplyDelete
  9. Curious, wouldn't it be more appropriate to copy the Field values, rather than the Property values?

    Otherwise fields with no public property accessor, and Read Only fields which rely on a value being set during construction will not be cloned correctly.

    ReplyDelete
  10. Anonymous9:03 AM

    In cloning an object, it is possible that some of the properties could have a value of nothing, which will throw an exception at:


    Item.SetValue(newObject, IClone.Clone, Nothing)


    Thus, wrapping this with a Try/Catch block fixes this little issue.

    ReplyDelete
  11. The way to fix the Dictionary is to change Me(0).GetType to
    Me.First.GetType

    ReplyDelete

  1. When working with Javascript using the jQuery library, there are often several alternative ways of using selectors or methods to acquire a reference to an element in the DOM, and when performance is an issue, generally the desire is to use the best performing (i.e. fastest) of these alternatives for any given scenario.

    A common requirement is when you need to acquire the nth child element of a jQuery DOM reference. Suppose, for example, you need to get the fourth child element in an unordered list.  What is the fastest way to do this? 

    I've seen a number of different answers to questions like these, but the correct one is usually 'it depends'. There are many different ways of selecting DOM elements in jQuery, and in choosing the best one, you often need to know additional information.  For example, if your script will:
    • already have a jQuery reference variable to the parent
    • know enough information to include a filter of the children
    • know whether there is only a single parent DOM element or not
    any combination of the above can change what the fastest way to get what you want is going to be.  In addition, over time, different methods may change in terms of performance comparison, meaning that what version of jQuery you are using may affect the best method to use in a given situation.  (Additionally, the browser actually running the script can sometimes make a difference as to what method will be fastest, but this may not be something you have control over.)

    Continuing with our example, suppose we know that there will be a single root parent with an id of "ul1", and we need to acquire a reference to the fourth list item.  In this case, we can specify a child selector ("li").  Assuming we do not already have the parent element stored in a variable,  there are several different methods we could use.  I created a test for this at http://jsperf.com/nth-element/4.  Of the ones tested, selecting the parent element, and then passing the element by index (3 in this case) from the children method back into jQuery was the fastest:

    $($("#ul1").children("li")[3])

    If, on the other hand, we have many elements matching the parent selector, as at this test: http://jsperf.com/nth-child-element-using-jquery-for-generic-tag/2, the fastest method seems to be to let jQuery know in one string all of the information you can, e.g.

    $("ul li:nth-child(4)")

    Supposing you don't have a filter for the child elements.  We can simulate this with our example by leaving out the 'li' tag - see http://jsperf.com/getting-first-child-element-using-jquery/3'.  The fastest method in this case was:

    $('ul > :first-child')

    This was actually faster than without the > operator, e.g.

    $('ul :first-child')


    Again, the more we can tell jQuery ahead of time, the faster we can make our query perform, if we change it accordingly.  Suppose we go back to our first example of needing a child element of "#ul1", as at this test: 

    As you might expect from looking at the above results, the fastest method is now:

    $($('#ul1').children()[0]);


    Figuring out which of the many possible techniques will give you the best performance can be interesting, but does it really make a difference?  In some cases, it may not.  jQuery DOM selection is a highly optimized.  However, in many cases (such as with a large DOM, a highly interactive web site, or a mobile web application that may be running on a smart-phone with limited computing power, using the right technique to get the blazing fast performance you need can be essential.  There is plenty of marketing data that confirms that web site speed and responsiveness is a major factor in retaining and acquiring new visitors / users. 

    With so many possible ways of selecting DOM elements in jQuery given various scenarios, the next question becomes - how do I keep track of the fastest methods for the different kinds of situations?  

    That's when the ability to easily whip up some jQuery plugins and put them into a descriptive jQuery namespace (such as 'quick') can be very useful.  You can add methods as needed, and over time develop your own customized and optimized jQuery library.  I'll cover that in a future post.

    (If you have discovered a fast way to select DOM element(s) given a particular scenario, feel free to share)
    0

    Add a comment


  2. I have worked on a number of projects in which we have a team of developers working on an application.  Let's say you have a small team of eight, and you are working on an enterprise CRM web application consisting of a couple of hundred views and associated functionality (code) of a couple of hundred-thousand lines.  You want to group similar functionality for organizational purposes and to maximize code-reuse and ease-of-maintenance, because this amount of code is extraordinarily difficult to manage without some strategy of this type - so you namespace your logical code groups.  You now just have 7 or 8 hundred namespaces - much better, but still extremely difficult to manage.  By further grouping of related namespaces into nested namespaces, you now have 7 primary namespaces, each consisting of 10 secondary namespaces and each of these containing 10 tertiary namespaces.  You now have a system that you can work with.  Trying to avoid using namespaces in this kind of situation is like saying there really is no need to allow folders on a pc - just throw all your files in one place.  Trying to avoid nested namespaces would be like saying ok, you can have folders on your pc, but no nested folders.  It just isn't a realistic option.
    If you don't have a need to nest namespaces in the projects you work on then certainly there is no reason to artificially create an over-engineered solution, but for those who work in enterprise environments, the concept of not having nested namespaces is unthinkable because it would make some projects impossible to do, or at least overtly expensive.  The fact that true (nested) namespacing is not readily accesible in Javascript is a big part of the reason that so much of the software engineering in enterprise web applications remains server side to this day, and will continue to be for the foreseeable future - while you do not have the processing power server-side that you do with your collective client-side computing base, for organizational purposes it makes what would be an otherwise impossible situation manageable.  If Javascript and client-side applications are ever going to become a mainstream, primary engineering paridigm in business then a viable nested namespacing solution must be realized.  This would benefit the development community as a whole because it would lead to greater support and innovation as well as drive browser functionality and standards development and adoption for client-side technologies in a much bigger way than is currently the case.
    It is important to realize that namespacing addresses three very major issues in enterprise development, and collisions is only one of those.  The others are organization and multiple developers being able to work simultaneously on a single application project. 
    Regarding organization, when projects are large and you have a team that is geographically separated, something other than a few javascript files, and using folders to organize them, becomes mandatory.  You will in fact reach a point where it is not physically possible to maintain your code base in any other manner than a centralized global application cache or repository of some sort with a logical ordering system. 
    Having multiple developers being able to work simultaneously on a single application project with a million lines of code also means that you cannot use a simple idea like using a variable name prefix for namespacing.  There is no realistic way to implement nested namespaces using this method, and you cannot dynamically and simultaneously add to your code-base in a meaningful way as a team using this approach.  While such a method is fine for a small project or a C application that is written by a small group for a very specific purpose, it just is not realistic for many medium-to-large business-oriented development projects.
    Unless you have worked in the corporate sector it may not seem that things like namespacing, nested namespacing, namespacing across documents, etc. is really necessary, but in a modern enterprise setting there are a whole new set of challenges that individual developers and smaller firms may never see, and these are time-tested and indispensible methods for meeting these challenges in a realistic manner.  To the extent that the development community as a whole can assist in helping meet these challenges with the Javascript language, the language will enjoy more widespread adoption and support from those who have the resources to have the biggest positive impact on the field as a whole.
    Again, it is important to note that over-engineering an application in an attempt to mimic something such as techniques used in enterprise IT does not make an application better or a developer more 'professional'.  Different projects have different logistical concerns and there are a great many web applications that are over-engineered for no good reason.  This sometimes happens when those who routinely work on enterprise projects attempt to apply principles from those projects to a different type of situation, such as a smaller, maintainable javascript library of a few thousand lines of code, where such techniques are not needed and just add a lot of cruft.  There are those who are more specialized in working with a smaller code / user / developer base, and may see this as unnecessary - which in many cases it is - but it would not be wise to assume that such techniques are unneccessary in all situations.  There are a great many professional developers who routinely and efficiently work with enormous libraries of code every day by relying on techniques such as nested namespacing as an absolute necessity.
    0

    Add a comment

  3. When I first came across the ? operator in C# I didn't know what I was looking at, which is probably why some C# programmers like to use it (ahh the power of esoteric knowledge!) However, as I've come to appreciate more the economy of some C# conventions, I find it very convenient at times. For those unfamiliar with it, the ? operator (known as a ternary operator) is a sort of short hand for assignment statements based on a condition. The basic syntax is:
    [variable name] = [boolean or condition] ? [value to assign if condition is true] : [value to assign if condition is false]

    For example, this code:

    if (x == 0)
    {
    y = 1;
    }
    else
    {
    y = x;
    }
    can be shortened to this statement:

    y = (x == 0) ? 1 : x;
    This may beg the question of code readability, but this has never been as high a priority in C# as in VB. C# developers tend to prefer tight, efficient code. Take, for example, the newer method available for declaring properties:

    private string name;

    public string Name
    {
    get
    {
    return name;
    }
    set
    {
    name = value;
    }
    }
    can now be written as

    public string Name { get; set; }
    and I can tell you that I use the latter whenever possible. This isn't a knock against VB (I was a VB programmer for many years before switching over to primarily writing code in C#) but simply an observation of one of the different approaches of the two languages.

    In any event,the ternary ? operator can be an effective technique for tightening up your code in the appropriate circumstances.
    1

    View comments

  4. There are a large number of sources on the internet describing how to create and/or install a Windows service in .Net, but as I was developing one for the company I work for I did not find one that comprehensively covered everything I needed to know so I thought I'd write a blog entry on this topic. (Note: If you have trouble reading any of the screen shots below, click on the screen shot for a larger image.)

    Creating the service in Visual Studio 2008 is relatively simple. To do so, create a new project using the Windows Service template:


    Once you have the project in your solution explorer, right click on the service (named Service1.cs by default) and select View Code. This will bring up a skeleton class for your service where you can add code to execute in the OnStart and OnStop methods for when your service starts and stops, respectively.

    Once I got this far I went ahead and wrote my code and was ready to begin debugging it. However, as you may already know, you cannot simply run a service in debug mode from Visual Studio. You have to install it, get it running, and then attach to it as a process. I googled on how to install a service and found this page on MSDN where it said to access the directory in which your project's compiled executable file is located and run InstallUtil.exe from the command line (i.e. installutil yourproject.exe). I tried this and got the message 'installutil' is not recognized as an internal or external command, operable program or batch file. Microsoft forgot to mention that installutil.exe is not part of the environment path by default, so I had to hunt it down. Doing a file search, I found it in the C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ directory. Anticipating that I would be running it more than once, I added this to the command line path so that I could execute it from anywhere in my file system. To do this, right click on My Computer in Windows explorer, select Properties, click on the Advanced tab, click on the Environment Variables button, select the Path variable, click on the Edit button, add a semicolon to the existing Path value, followed by "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\;" and click the OK button.


    Okay, that wasn't so bad, I thought. I brought up the command prompt, changed to the directory where my exe file was being built, and Windows now knew what installutil was when I typed it in. So, following my instructions from MSDN, I typed in "installutil myService.exe". This generated some output in the command window which I largely ignored other than the last few lines which seemed to indicate the install was successful. However, when I went to look at the services running on my machine my service wasn't there. I went back to my command window and read the output more carefully, and saw "No public installers with the RunInstallerAttribute.Yes attribute could be found". What the heck?

    After a little more research, I discovered I needed to add an installer to my project in order for the command line utility to work. This is easy enough to do once you know about it - simply bring up your service designer and right click somewhere on the gray background area(if you have added any components, make sure you are selecting the service itself and not a component) and then select Add Installer. This adds an installer class with two components - a service installer and a service process installer. If you click on the service installer component and look at the properties, you can see where you can name your service (using the ServiceName property) and specify whether to start it automatically or manually (in the StartType property). Next click on the service process installer component and in its properties you can specify what account to run your service under via the Account property (if you select user you will need to provide the name and password of the user the service will run under). I selected Local System as I didn't want to have to supply credentials and I knew this would have access rights to the file system by default. (For some applications, this may not be the best choice if security is an issue, but you should also be aware that the other choices of LocalService or NetworkService may not have the access needed to actually run your service by default.)


    Once I had done all of this, I did another build of my project and then went back to the command line. Installutil worked. I could see the service in my list of services. I was happy - until I realized my service wasn't working right. It turned out that this was because I was using an App.config file to initialize some settings. After a little more research, I discovered I needed to copy this to the location of the executable that was being run as the service and rename it to the name of the executable but with a .config extension (i.e. myService.exe.config.) I did this, stopped and restarted the service, and all was well.

    After some reflection, however, I thought "Why do I have to start the service manually after I install it? Is there a way to have it start automatically when it is installed?" It turns out there is a way, and it is actually pretty simple. To have your service start upon installation, bring up the code-behind for your project installer (right-click on it in Solution Explorer and select View Code). You should see something like this:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Configuration.Install;
    using System.Linq;

    namespace myService
    {
    [RunInstaller(true)]
    public partial class ProjectInstaller : Installer
    {
    public ProjectInstaller()
    {
    InitializeComponent();
    }
    }
    }
    What we want to do here is have the Installer class start up our service after installation. It turns out the Installer class has an event called Committed that occurs after a successful installation. All that is needed is to add an event handler for this event and put code in it to start the service. To add the event handler, add this line of code after InitializeComponent():

    this.Committed += new InstallEventHandler(ProjectInstaller_Committed);
    and this new function to your class:

    void ProjectInstaller_Committed(object sender, InstallEventArgs e)
    {

    }
    (Intellisense will do most of the work for you if you hit the TAB key at the appropriate times.) Now we just need to add the code to actually start the service when this event occurs. First add this namespace to your using statements:

    using System.ServiceProcess;
    Next, in your event handler function, add this code:

    ServiceController sc = new ServiceController("myService");
    sc.Start();
    (Replace "myService" with your actual service name.) When you are done, your project installer class should look something like this:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Configuration.Install;
    using System.Linq;
    using System.ServiceProcess;

    namespace myService
    {
    [RunInstaller(true)]
    public partial class ProjectInstaller : Installer
    {
    public ProjectInstaller()
    {
    InitializeComponent();
    this.Committed += new InstallEventHandler(ProjectInstaller_Committed);
    }

    void ProjectInstaller_Committed(object sender, InstallEventArgs e)
    {
    ServiceController sc = new ServiceController("myService");
    sc.Start();
    }
    }
    }
    When you are done, save and build your project. You should now find that upon installation, your service is started automatically. This was a plus for me because it was one less set of instructions that I needed to supply to our deployment group. Along these lines, I began thinking about what else I could do to make deployment simpler, and decided to go ahead and add a setup project to my solution. This would mean (in theory) that all that would be needed to install the service would be to double-click on an msi file rather than mucking about with the command prompt and installutil. To add a setup project for your service, right-click on the solution in Solution Explorer and select Add->New Project. From the project templates, select Setup Project (usually under Other Project Types->Setup and Deployment in VS 2008.)


    Once you have added a setup project to your solution, you need to add a Custom Action to your setup project so that it knows what to install. To do this, right-click on your setup project in Solution Explorer and select View->Custom Actions. This will bring up the Custom Actions window. Right click on Custom Actions in this window and select Add Custom Action. This will bring up a dialog box. Double-click the Application Folder and click on the Add Output... button. This brings up another dialog box. It should already have the primary output for your service project selected using the Active configuration, so just click OK and then OK again.


    Once you have done so, it will add the necessary Custom Action to the setup project to install your service.


    Once you have done this, build your setup project. Assuming everything has been done correctly, once the build completes you will find an msi file in your ouput directory. If you installed your service manually using installutil then uninstall it the same way (with the /u switch). Double-click on the msi file in Windows explorer and a little setup wizard will guide you through the installation process of your service. If you have an app.config file, it will even rename and move this for you, rather than having to do it manually as with using installutil.

    I did this and thought "great! I'm done!" but something was nagging at me. It was the fact that the setup wizard had an option to install the service for everyone or just me, and was defaulting to just me. I wanted this service to be installed for everyone when it was deployed. In the interests of further simplifying deployment instructions and eliminating another hazard, I wanted this to default to everyone. If you want to do this, it is fairly simple. Select the setup project in Solution Explorer and look at the properties (F4 brings up the properties window if you don't see it). There is a property called InstallAllUsers that by default is set to false. Set it to true, and when you run the setup project, it will default to everyone rather than just me. After further reflection I decided that I wanted to remove the option altogether, since I wanted to always install for everyone. If you want to do this, right-click on your setup project in Solution Explorer and select View->User Interface. This will bring up the user interface window, which is basically a tree-view of the setup screens the user will see. If you click on Installation Folder in this window and look at the properties, you will see a property called InstallAllUsersVisible. If you set this to false, the setup project will not show this option.


    I was pretty happy at this point. Deploying the service couldn't be simpler. I tested it myself. I installed it. I double-clicked the msi file again and was able to uninstall it, but I noticed there was also an option to repair. I found that if I selected repair rather than uninstall, I would get a message saying "Error 1001. The specified service already exists". This was not a show-stopper, but it was annoying. I don't like sending out applications for deployment knowing they can generate an error. What if the config file was deleted or changed it such a way that the service didn't work right? What if the service was removed manually? Sure the user could uninstall and then reinstall the service, but it would be much nicer if they could choose repair and it would work rather than generating an error.

    It turns out the reason for the error is that when selecting repair, it was trying to install the service again even if it was already installed. If the service was already on the machine, I didn't want repair to try to put it on there again and then generate an error. To fix this, you have to go back to your Custom Actions screen (right-click on your setup project in Solution Explorer, select View->Custom Actions.) Under the install folder, select the Primary Output for your service and look at its properties. There is one called Condition. Set this property's value to Not Intalled (this is case sensitive.)


    Now the setup package knew not to install the service if it was already there, but I was still getting an error when I tried to run setup with the repair option. It was saying that it cannot start the service because an instance of the service is already running. I needed to go back to the code I added earlier to the project installer to automatically start the service and only have it do this if the service was stopped. To do this, I brought up the code-behind for my project installer, and modified the event handler as follows:

    void ProjectInstaller_Committed(object sender, InstallEventArgs e)
    {
    ServiceController sc = new ServiceController("myService");
    if (sc.Status == ServiceControllerStatus.Stopped)
    {
    sc.Start();
    }
    }
    After doing this, I did a build of my service project and a build of my setup project (note that if you do a build on your solution, it will not build the setup project by default.) Using the repair option when running setup now worked as desired and did not generate any errors. I was done with setting up the installation of the service.

    Back to the debug issue. Now that I had the service installed, I wanted to hit some breakpoints in my code. In order to do this, make sure your service is running. Then while your project is up in Visual Studio, select Debug->Attach to process. Check the Show processes from all users checkbox (otherwise you will only see a grayed-out, disabled process with vshost as part of your service name which you cannot attach to.) Find your service name in the list of processes, select it, and click the Attach button. You will now be able to hit breakpoints in your service (although you may not be able to hit breakpoints put directly in the OnStart method due to timing issues.)
    1

    View comments

  5. Earlier versions of Silverlight did not have a timer class but now in 2.0 one is available. The class is called DispatcherTimer and is located in the System.Windows.Threading namespace. Other than this it behaves just like a regular .NET timer, as the code sample below will show.

    First add a reference to the namespace at the top of your code-behind page:

    using System.Windows.Threading;

    Then you can initialize the timer and start it wherever you want:

    // Declare the timer variable
    DispatcherTimer timer = new DispatcherTimer();
    // Set the interval in milliseconds (the example below sets the interval to 1 second)
    timer.Interval = new TimeSpan(0, 0, 0, 0, 1000);
    // Now add an event handler for when the timer ticks (intellisense can save you some typing here)
    timer.Tick += new EventHandler(timer_Tick);
    // Everything is set, and you can now start your timer
    timer.Start();

    Don't forget this is running asynchronously so you may want to stop the timer and then start it again when your code evoked by the timer is complete, as demonstrated in the timer tick event error handler below (In this example, the myFunction function will be called on one second intervals):

    void timer_Tick(object sender, EventArgs e)
    {
    ((DispatcherTimer)sender).Stop();
    myFunction();
    ((DispatcherTimer)sender).Start();
    }
    0

    Add a comment

  6. Consuming a web service in Silverlight is a little different than in a standard web application. Assuming you are using the Visual Studio IDE with Silverlight installed, when you create a service reference in your Silverlight project, some methods and events are created for that reference so that the call to the web service method can be (and actually must be) done asynchronously. This can be a little confusing if you don't know what is going on. For example, when you instantiate your service reference to the web service, you won't see the web method names that you might be expecting. They will all be there, but they will have 'Async' added to the end of the name. Also, since the calls are asynchronous, the code will not wait for the return data before continuing execution. This means you have to setup an Event Handler for when the call is completed and returns your data.

    This is what your code will look like to instantiate the service and setup the event handler (luckily intellisense will do most of the typing for you if you hit TAB when appropriate):

    MyServiceReference.MyServiceNameSoapClient mySvc = new MyServiceReference.MyServiceNameSoapClient();
    mySvc.myWebMethodCompleted += new EventHandler<myNameSpace.MyServiceReference.myWebMethodCompletedEventArgs>(mySvc_myWebMethodCompleted);

    now you are ready to call your web method asynchronously:

    mySvc.myWebMethodAsync();

    The final step is to handle the return data once the call has completed in an Event Handler as specified above. The handler's EventArgs parameter will contain the results of your web method call in its Result property:

    void mySvc_myWebMethodCompleted(object sender, myNameSpace.myServiceReference.myWebMethodCompletedEventArgs e)
    {
    myTextBlock.Text = e.Result.ToString();
    }
    0

    Add a comment

  7. Deploying a Silverlight app is pretty simple. Just put the compiled assembly (and any resources your app depends on) on the web server, and map a virtual directory (under the default website) to it in IIS. If you have done this and it still isn't working, IIS may not have the mime types needed for WCF/Silverlight. This is easy to fix. Just add the following mime maps to the default website in IIS:














    ExtensionContent Type
    .xamlapplication/xaml+xml
    .xap application/x-silverlight-app
    .xbapapplication/x-ms-xbap

    For IIS 5 and 6 you can do this by bringing up the properties of the default website, click on the Http Headers tab, and then click on the File Types button under "Mime Mapping".

    Note - if you want to add all mime types used by WPF, add these as well:
















    ExtensionContent Type
    .applicationapplication/x-ms-application
    .deployapplication/octet-stream
    .manifestapplication/manifest
    .xpsapplication/vnd.ms-xpsdocument
    0

    Add a comment

  8. I found in a recent Silverlight application that I was working on that I needed to pass the username to a web service call, and that the standard methods I was accustomed to using in .NET were not available in the Silverlight application. After a little research on the web and some trial and error, I was able to do this by retrieving this information in the web application that was hosting the Silverlight application control, and then using Silverlight application InitParams to pass the data back to the Silverlight application. (This seemed to me simpler and more elegant than the alternative method, that of creating a web service for the sole purpose of providing a username to Silverlight.) Below is a step-by-step process on how to do this.

    Step 1 - Retrieve the username in the web application hosting your Silverlight application
    In order to do this, you will need a code-behind page for your page hosting the Silverlight control, (which is not created by default for the Silverlight aspx test page.) To add this, first you need to modify the first line of your aspx page hosting the Silverlight app. Initially it will look something like this:

    <%@ Page Language="C#" AutoEventWireup="true" %>

    You will need to add the CodeBehind and Inherits attributes to this to point to the codebehind page that you will be adding. Assuming you have just created a new Silverlight app and are using the pre-generated aspx test page, the modified first line will look something like as follows:
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SilverlightApplication1TestPage.aspx.cs" Inherits="SilverlightApplication1.Web.SilverlightApplication1TestPage" %>
    Next we need to add the actual codebehind page that the above refers to. To add this, right click on your web application project, select Add->New Item, select the Code File template, and give it the same name as the aspx page hosting your Silverlight app (in our example this would be SilverlightApplication1.aspx.cs). This page will be blank by default, so we will want to add in the following to complete our tie-in with its aspx parent page and handle the page load event:

    using System;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    namespace SilverlightApplication1.Web.Web
    {
    public partial class SilverlightApplication1TestPage : System.Web.UI.Page
    {

    protected void Page_Load(object sender, EventArgs e)
    {

    }
    }
    }
    In order to be able to reference the Silverlight control programmatically, we also need to declare it. Assuming it has the default name of Xaml1, we would add a line below the class declaration as follows:

    protected global::System.Web.UI.SilverlightControls.Silverlight Xaml1;

    Step 2 - Retrieve the Username
    We can now retrieve the username using the standard .NET framework method. To do this, we first add a line to the top of the codebehind page to reference the System.Security.Principal namespace:

    using System.Security.Principal;

    We can then add the code to retrieve the username using the WindowsIdentity.GetCurrent method in the Page Load event:

    string userName = WindowsIdentity.GetCurrent().Name.ToString();

    Step 3 - Pass the Username as an InitParameter to the Silverlight application
    The Silverlight application object as defined by App.xaml and App.xaml.cs in the Silverlight app has a a startup event object called InitParams that is a dictionary of key value pairs and is empty by default. To populate this programmatically with values in the hosting web application, we set the property of the Silverlight control called InitParameters to our key/value pair in the format of a string "key=value". Continuing in our example, in the page load event under the line that retrieves the username as described above, we would add the following line of code:

    this.Xaml1.InitParameters = String.Format("UserName={0}", userName);
    At this point we are done with the web hosting application and can now retrieve this value in the Silverlight app. Our entire codebehind page for the hosting aspx page will now look something like this:

    using System;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Security.Principal;

    namespace SilverlightApplication2.Web.Web
    {
    public partial class SilverlightApplication2TestPage : System.Web.UI.Page
    {

    protected global::System.Web.UI.SilverlightControls.Silverlight Xaml1;

    protected void Page_Load(object sender, EventArgs e)
    {
    string userName = WindowsIdentity.GetCurrent().Name.ToString();
    this.Xaml1.InitParameters = String.Format("UserName={0}", userName);
    }
    }
    }

    Step 4 - Retrieving the username via the InitParams collection in the Silverlight Application
    When you open the App.xaml.cs codebehind page in the Silverlight application, you will see an auto-generated event handler for the Silverlight application startup event as follows:

    private void Application_Startup(object sender, StartupEventArgs e)
    {
    this.RootVisual = new Page();
    }
    In this event we can use StartupEventArgs to retrieve our username via the InitParams collection, but we need a place to store it, so we will create a property first, under the class declaration, as follows (note this uses the C# shortened notation for a simple property):

    public string UserName { get; set; }
    Now, going back to our Application_Startup event handler, we will add the line to populate this property with the username retrieved from the StartupEventArgs InitParams collection that we populated earlier on the web application side. The syntax for this (following our example thus far) is as follows:

    UserName = e.InitParams["UserName"];
    We can now reference this property in our Page.xaml.cs codebehind if needed by creating a reference to the current application object and then referencing our UserName property, as the following two lines of code illustrate:

    App currentApp = ((App)Application.Current);
    string userName = currentApp.UserName;
    and Voila! In my case, I was now able to pass that username as a parameter to a web service call from the codebehind of my Page.xaml in my Silverlight application.
    3

    View comments

  9. Needing to be able to clone an object is a common requirement when working in .NET, since simply assigning an object instance to a new variable name just adds a reference pointer to the existing object and sometimes you need to be able to create a new instance that is an exact copy of the existing one.

    For many of the existing classes in .NET, the clone method is available for just this purpose, but for custom classes you have written yourself you will need to implement the ICloneable interface (or just write your own clone method). For deep cloning, where you need to have all objects, including child objects, to be cloned rather than just assigning reference pointers to existing objects, this can be a little tricky. One method is to serialize the class into a memory stream and deserialize it to a new object, but the drawback here is that you can only clone classes that are binary-serializable. My classes are mostly XML serializable, so I wanted to use a different approach.

    A search on the web brought up various samples of code to do deep cloning using reflection and recursion, but it took a little work and debugging on my part to get this approach to work correctly.

    The first step was to create a base class that implements the ICloneable interface and uses reflection to clone the object, along with recursion for deep cloning child objects. I got a head start on this from a code sample I found perusing The Code Project (http://www.codeproject.com), so props go to Renfield78 at the code project for his post that got me started on this. Anyway, to make a long story short, with a little work and some debugging I was able to create base class in VB.NET that deep cloned object classes that inherit from it.

    This code worked fine until it ran into properties based on Dictionary and/or List classes. Since I use these two generic collection classes frequently, I wrote two classes that inherited from these that implemented the ICloneable interface as well, after which I was able to clone a fairly deep class-hiearchy successfully.

    The cloneable dictionary class (in simplified form) looks like this:


    Imports System.Reflection

    Public Class CloneableDictionary(Of T)
    Inherits Dictionary(Of T)
    Implements System.ICloneable

    Public Function Clone() As Object Implements System.ICloneable.Clone
    Dim NewDictionary As New CloneableDictionary(Of T)

    If Me.Count > 0 Then
    Dim ICloneType As Type = Me(0).GetType.GetInterface("ICloneable", True)
    If Not (ICloneType Is Nothing) Then
    For Each Value As T In Me
    NewDictionary.Add(CType(Value, ICloneable).Clone)
    Next
    Else
    Dim MethodsList() As MethodInfo = Me(0).GetType.GetMethods
    For Each Value As T In Me
    NewDictionary.Add(Value)
    Next
    End If
    Return NewDictionary
    Else
    Return NewDictionary
    End If
    End Function

    End Class


    The cloneable list class is likewise pretty simple:


    Imports System.Reflection

    Public Class CloneableList(Of T)
    Inherits List(Of T)
    Implements System.ICloneable

    Public Function Clone() As Object Implements System.ICloneable.Clone
    Dim NewList As New CloneableList(Of T)
    If Me.Count > 0 Then
    Dim ICloneType As Type = Me(0).GetType.GetInterface("ICloneable", True)
    If Not (ICloneType Is Nothing) Then
    For Each Value As T In Me
    NewList.Add(CType(Value, ICloneable).Clone)
    Next
    Else
    Dim MethodsList() As MethodInfo = Me(0).GetType.GetMethods
    For Each Value As T In Me
    NewList.Add(Value)
    Next
    End If
    Return NewList
    Else
    Return NewList
    End If
    End Function

    End Class

    Hopefully the above should be pretty self-explanatory. So long as you inherit from or use these classes in place of the base classes and the collections contain objects that implement the ICloneable interface (as shown below), these can be used with a deep cloning base class.

    The base class for all your other object classes will then need to look something like this:


    Imports System.Reflection

    Public MustInherit Class CloneableObject
    Implements System.ICloneable

    Private Function Clone(ByVal vObj As Object)
    If Not vObj Is Nothing Then
    If vObj.GetType.IsValueType OrElse vObj.GetType Is Type.GetType("System.String") Then
    Return vObj
    Else
    Dim newObject As Object = Activator.CreateInstance(vObj.GetType)
    If Not newObject.GetType.GetInterface("IEnumerable", True) Is Nothing AndAlso Not newObject.GetType.GetInterface("ICloneable", True) Is Nothing Then
    'This is a cloneable enumeration object so just clone it
    newObject = CType(vObj, ICloneable).Clone
    Return newObject
    Else
    For Each Item As PropertyInfo In newObject.GetType.GetProperties
    'If a property has the ICloneable interface, then call the interface clone method
    If Not (Item.PropertyType.GetInterface("ICloneable") Is Nothing) Then
    If Item.CanWrite Then
    Dim IClone As ICloneable = CType(Item.GetValue(vObj, Nothing), ICloneable)
    Item.SetValue(newObject, IClone.Clone, Nothing)
    End If
    Else
    'Otherwise just set the value
    If Item.CanWrite Then
    Item.SetValue(newObject, Clone(Item.GetValue(vObj, Nothing)), Nothing)
    End If
    End If
    Next
    Return newObject
    End If
    End If
    Else
    Return Nothing
    End If
    End Function

    Public Function Clone() As Object Implements System.ICloneable.Clone
    Return Clone(Me)
    End Function

    End Class


    Assuming all of your custom classes derive from the above and all properties that are based on dictionary or list objects use the appropriate ICloneable implementation (as show in the first two code samples), these three classes in conjunction should provide most of your needs in being able to deep clone your own custom classes.
    11

    View comments

    1. Anonymous10:51 PM

      Good for people to know.

      ReplyDelete
    2. Anonymous7:25 AM

      Any tips on how to integrate cloneable list class inside the base class?

      ReplyDelete
    3. To integrate the cloneable list or dictionary classes inside the base class, first create your own list or dictionary class that inherits from the cloneable list or dictionary classes. Then create your main class and have that inherit from the base cloneable class. You can then add your inherited list or dictionary as a member of this main class, and when you clone the main class it should be able to clone the dictionary or list member also.

      ReplyDelete
    4. Anonymous1:04 AM

      Thanks for your quick response.

      It now works :)

      I sent you an email with som more questions including a code sample.

      ReplyDelete
    5. Anonymous7:10 AM

      One correction to my comment. You don't have to inherit from the list or dictionary classes, you can just create your list or dictionary object directly from these classes and then add them to the main base class as members, at which point the base class clone method should work properly.

      ReplyDelete
    6. (NOTE: Thanks to Kay for this comment. This was emailed to me and I decided it would be good to post here. If you need to use an inherited class of the CloneableList class rather than instantiating directly from it, this looks like a good solution.)

      Kay's Comment:

      I have got it to work now, but I had to do some tweaking.

      My code:

      public class MyObjectList<T> : CloneableList<T>
      {
      public override object Clone()
      {
      MyObjectList<T> NewList = new MyObjectList<T>(); // CloneableList<T> NewList = new CloneableList<T>();
      if (this.Count > 0)
      {
      Type ICloneType = this.GetType().GetInterface("ICloneable", true);
      if ((ICloneType != null))
      {
      foreach (T Value in this)
      {
      NewList.Add((T)((ICloneable)Value).Clone());
      }
      }
      else
      {
      foreach (T Value in this)
      {
      NewList.Add(Value);
      }
      }
      return NewList;
      }
      return NewList;
      }
      }

      I had to set "your" CloneableList class Clone method to virtual so I could override it because it returned a list of type CloneableList which caused an error since I need the returned list to be of type MyObjectList.

      ReplyDelete
    7. Your cloneable dictionary code is the same as the cloneable list code.

      ReplyDelete
    8. Anonymous5:21 AM

      Yes, the dictionary code does not compile as is.

      I don't need that so will use the other two.

      Thanks!! :-)

      ReplyDelete
    9. Curious, wouldn't it be more appropriate to copy the Field values, rather than the Property values?

      Otherwise fields with no public property accessor, and Read Only fields which rely on a value being set during construction will not be cloned correctly.

      ReplyDelete
    10. Anonymous9:03 AM

      In cloning an object, it is possible that some of the properties could have a value of nothing, which will throw an exception at:


      Item.SetValue(newObject, IClone.Clone, Nothing)


      Thus, wrapping this with a Try/Catch block fixes this little issue.

      ReplyDelete
    11. The way to fix the Dictionary is to change Me(0).GetType to
      Me.First.GetType

      ReplyDelete
Popular Posts
Popular Posts
About Me
About Me
Blog Archive
Subscribe
Subscribe
Subscribe
Subscribe
Loading
Dynamic Views theme. Powered by Blogger. Report Abuse.