The System.ComponentModel namespace along with System.ComponentModel.Design and System.ComponentModel.Design.Serialization contains many classes. Most of the classes deal with support for building (design-time) and deploying (run-time) pluggable components. Check out the following online articles on the ComponentModel:
“Creating Designable Components for Microsoft Visual Studio .NET Designers,” Shawn Burke, http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/pdc_vsdescmp.asp.
“Component Programming Essentials,” http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguidnf/html/cpconcomponentprogrammingessentials.asp?frame=true.
This class represents a base class that is used for all licenses. Licensing a component involves the use of the LicenseProviderAttribute, LicenseProvider, LicenseManager, LicenseContext, and LicenseException classes. For a simple implementation, the LicFileLicenseProvider class is provided with the SDK. To enable licensing in a windows control, you could follow the example in Listing B.41 (see the License solution in the License directory).
[LicenseProvider(typeof(LicFileLicenseProvider))] public class UserControl : System.Windows.Forms.UserControl { private License license = null; private System.Windows.Forms.Label label; private System.ComponentModel.Container components = null; public UserControl() { // Add Validate to the control's constructor. license = LicenseManager.Validate(typeof(UserControl), this); // This call is required by the Windows.Forms Form Designer. InitializeComponent(); } ... protected override void Dispose( bool disposing ) { if( disposing ) { if( components != null ) components.Dispose(); if (license != null) { license.Dispose(); license = null; } } base.Dispose( disposing ); } |
First, notice that the control has LicenseProviderAttribute applied to the class. The specific provider is specified as LicFileLicenseProvider. If you were to license a class, the code would be similar. Listing B.42 shows an example of licensing a control class.
[LicenseProvider(typeof(LicFileLicenseProvider))] public class UserControl : IDisposable { private License license = null; public UserControl() { // Add Validate to the control's constructor. license = LicenseManager.Validate(typeof(UserControl), this); } ... public void Dispose() { if (license != null) { license.Dispose(); license = null; } } |
The only provider that is shipped with the .NET Framework is LicFileLicenseProvider. This class looks for a file type-name.lic, where type-name is the full name of the type being licensed. Here, it would be LicensedControl.UserControl.lic because the namespace is LicensedControl and the class name is UserControl. On startup the control is created as follows:
control = new LicensedControl.UserControl();
The constructor is called, and in the constructor, a call is made to validate the control. The LicFileLicenseProvider class looks for the .LIC file and reads the first line. If the first line of the file ends in is a licensed component, then the validation returns true and the object can be instantiated. If the file is not found or is not valid, then a LicenseException exception is thrown and the construction of the object fails.
You need to modify the license class to provide custom license verification. To do this, you need to build a class that derives from LicenseProvider. A snippet from the new class is shown in Listing B.43.
[LicenseProvider(typeof(TimeBombLicenseProvider))] public class UserClass { private License license = null; public UserClass() { // Validate the license. If this fails, the constructor // will not complete and the constructor will fail. license = (TimeBombLicenseProvider.TimeBombLicense)LicenseManager.Validate(typeof (UserClass), this); } |
The implementation of the LicenseProvider and the License class looks like Listing B.44.
An attribute has been added to specify the LicenseProvider as TimeBombLicenseProvider. The LicenseManager is included in the class that inherits from License. Here, TimeBombLicense inherits from License. A partial listing of this code is shown in Listing B.45.
public class TimeBombLicense : License { private TimeBombLicenseProvider owner; private string key; private DateTime validStartTime; private DateTime validEndTime; public TimeBombLicense(TimeBombLicenseProvider owner, string key) { this.owner = owner; this.key = key; int startIndex = key.IndexOf(',') + 1; int endIndex = key.IndexOf(',', startIndex) + 1; this.validStartTime = new DateTime(Convert.ToInt64(key.Substring (startIndex, endIndex - startIndex - 1))); this.validEndTime = new DateTime(Int64.Parse (key.Substring(endIndex))); } . . . |
The two classes TypeDescriptor and TypeConverter allow for a flexible conversion scheme between types. To take advantage of this conversion, add an attribute to your class to indicate that a converter is available. It looks something like this:
[TypeConverter(typeof(ComplexConverter))] public class Complex {
Then you need to implement the converter. To implement a converter, you derive a class from TypeConverter and implement the required virtual methods. As a minimum, you need to implement the CanConvertFrom, ConvertFrom, and ConvertTo methods. The implementation looks like Listing B.46 (typeconverter.cs).
public class ComplexConverter : TypeConverter { // CanConvertFrom of TypeConverter public override bool CanConvertFrom(ITypeDescriptorContext context, Type st) { if (st == typeof(string)) { return true; } return base.CanConvertFrom(context, st); } // ConvertFrom of TypeConverter. public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string) { string[] v = ((string)value).Split(new char[] {','} ); return new Complex(double.Parse(v[0]), double.Parse(v[1])); } return base.ConvertFrom(context, culture, value); } // ConvertTo of TypeConverter. public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string)) { return ((Complex)value).Real + "," + (Complex)value).Imaginary; } return base.ConvertTo(context, culture, value, destinationType); } } |
Listing B.47 provides an example of using the conversion methods. Typically, these conversion methods are called from controls to convert from a sting in the property page of the IDE to a specific type that the component requires.
Complex c = (Complex)TypeDescriptor.GetConverter(typeof(Complex)). ConvertFromString("1.0 ,2.0"); string ds = (string)TypeDescriptor.GetConverter(c).ConvertToString(c); Console.WriteLine("{0} ,{1} <-> {2} ", c.Real, c.Imaginary, ds); |
3.17.23.130