Enterprise Library Custom Application Block (I)

Source: Internet
Author: User
1 Overview

Enterprise Library by Microsoft
Is an application.ProgramA collection of blocks. Although enterprise
Library contains many application blocks, but in many cases it still cannot meet specific requirements. This article describes how to build an application block to meet your needs.

This document is only an exampleCodeUse Enterprise Library to customize application blocks to speed up development (
Enterprise Library 3.1
But different construction methods have been used to describe. The original Article uses the top-down mode from the demand perspective, and this article is gradually built from the bottom up, in order to make the entire build process more
Clear and simple. At the same time, some necessary explanations are added to the objects contained in the Enterprise Library used during the construction process.

2 Requirements

Create an application block that can be used to manage application plug-ins. Actually, you can obtain the list of installed plug-ins.

3. configured Scheme

The Application Block of Enterprise Library is configuration-driven. Therefore, you should first consider how to save configuration information. First look at the required configuration file.

<Configuration>
<Configsections>

<Section name = "pluginconfiguration"
Type = "pluginloader. configuration. pluginloadersettings, pluginloader,
Version = 1.0.0.0, culture = neutral, publickeytoken = NULL "/>
</Configsections>
<Pluginconfiguration>
<Pluginproviders>
<Add name = "" type = ""/>
</Pluginproviders>
</Pluginconfiguration>
</Configuration>

In
In the configuration file, there is a configuration section pluginconfiguration for plug-in management. Its sub-element <pluginproviders>
Is the definition of the provider of various plug-ins. The plug-in provider is defined by the <add> element, where name is the provider's identity name and type
For the type of the provider, each provider can manage the corresponding plug-ins (in this example, only the list of corresponding types of plug-ins is obtained ).

4. basic configuration

Based on the preceding configuration file, we can define the configuration classes for plug-in management and the configuration classes for the provider data as follows:

Plug-in management configuration class: public class pluginloadersettings: serializableconfigurationsection
{
Public const string sectionname = "pluginconfiguration ";

Private const string providersproperty _ = "pluginproviders ";

Public pluginloadersettings (): Base (){}

[Configurationproperty (pluginloadersettings. providersproperty _)]
Public nametypeconfigurationelementcollection <pluginproviderdata, pluginproviderdata> pluginproviders
{
Get
{

Return (nametypeconfigurationelementcollection <pluginproviderdata,
Pluginproviderdata>) This [pluginloadersettings. providersproperty _];
}
}

}

Provider configuration class: public class pluginproviderdata: nametypeconfigurationelement
{
Public pluginproviderdata ()
: Base ()
{
}

Public pluginproviderdata (string name, type)
: Base (name, type)
{
}
}

Before describing these two classes, explain the following classes:

    • Serializableconfigurationsection.
      This is the class inherited by the plug-in configuration management class. From Enterprise Library
      Namespace: Microsoft. Practices. enterpriselibrary. Common. configuration. It indicates
      Configuration section for serialization and deserialization. Provides serialization and deserialization functions.
    • Configurationpropertyattribute. Declared to indicate that the identified property is a configuration property and the name of the configuration property is specified. The system. Configuration namespace from. NET Framework 2.0.
    • Nametypeconfigurationelement
      . Namespace: Microsoft. Practices. enterpriselibrary. Common. configuration. Indicates that
      The configuration element of the name and value attributes, which is required for the configuration of our plug-in provider.
    • Nametypeconfigurationelementcollection
      . The set of nametypeconfigurationelement, which has two generic parameters. The first is
      Nametypeconfigurationelement
      Object type. The second is the object type used to customize configuration elements in the collection. The second type must be automatically converted to the first type.

Therefore, the configuration class pluginloadersettings is a serializable configuration class and defines the name of the configuration section.
"Pluginconfiguration" and plug-in configuration set name "pluginproviders", and
The configurationpropertyattribute Class Identifier provides a set of plug-in providers based on the corresponding attributes. Because the configuration of the plug-in provider only requires
Name and value attributes, so you can directly inherit from the nametypeconfigurationelement class.

In this case, the configuration class can also be omitted from the serializableconfigurationsection and
Nametypeconfigurationelement, but from. NET Framework 2.0
The corresponding configuration section and configuration data class are derived here only to take advantage of the enhanced functionality of the Enterprise Library.

5. Abstract provider base class

After defining the required configuration, you can define the base class of the provider, as shown in the following figure: using Microsoft. Practices. enterpriselibrary. Common. configuration. objectbuilder;
Using system;
Using system. collections;
Namespace pluginloader
{
[Customfactory (typeof (pluginprovidercustomfactory)]
Public abstract class pluginprovider
{
Private type plugintype _;

Protected pluginprovider (type plugintype)
{
This. plugintype _ = plugintype;
}

Public abstract ilist getplugins ();

Protected type plugintype
{
Get {return this. plugintype _;}
}

}
}

Here, we can see the function of a provider: getplugins ()
The method is required. The plug-in provider provides a list of plug-ins of this type. The provider class uses the attribute class customfactoryattribute
. This attribute is used to specify the factory class used by the Enterprise Library to create the class it identifies. Here we use
Pluginprovidercustomfactory, which will be explained in the next section.

6. customized provider Factory

Next, pluginprovidercustomfactory is the enterprise library used to create
The factory class of the pluginprovider object, which is derived from assumerbasedcustomfactory.
. In the factory class, it is used to read configuration information from the configuration file (configuration source) and create the required configuration data class pluginproviderdata.
. Using Microsoft. Practices. enterpriselibrary. Common. configuration;
Using Microsoft. Practices. enterpriselibrary. Common. configuration. objectbuilder;
Using pluginloader. configuration;
Namespace pluginloader
{
Public class pluginprovidercustomfactory: ererbasedcustomfactory <pluginprovider, pluginproviderdata>
{
Protected override pluginproviderdata getconfiguration (string name, iconfigurationsource configurationsource)
{
Pluginloadersettings settings =
(Pluginloadersettings) configurationsource. getsection (pluginloadersettings. sectionname );
Return settings. pluginproviders. Get (name );
}
}
}

The generic type used by the basic classes is only used to implement the strong type. In the getconfiguration method, the name parameter is the name of the provider configuration, that is, add
The name; configurationsource parameter in the element is the configuration source information. This method is automatically implemented by the Enterprise Library according
Call the binding information of the customfactoryattribute.

In addition to pluginprovidercustomfactory to obtain configuration information, we also need another class, that is, the factory class pluginproviderfactory that truly creates the provider. The Code is as follows: using Microsoft. Practices. enterpriselibrary. Common. configuration;
Using Microsoft. Practices. enterpriselibrary. Common. configuration. objectbuilder;
Namespace pluginloader
{
Public class pluginproviderfactory: nametypefactorybase <pluginprovider>
{
Public pluginproviderfactory (iconfigurationsource configsource)
: Base (configsource ){}
}
}

The Code shows that the pluginproviderfactory is derived from the nametypefactorybase class, and the base class implements
Name/type automatically creates the object corresponding to the configuration information. If you need more complex processing, you can override the new () method. Because the configuration of our provider is
Name/type pairs, so you only need to implement a constructor.

Here we can use: iconfigurationsource configsource = configurationsourcefactory. Create ();
String providerconfigname = "configname"; // This is the name of the add element in the configuration section. Pluginproviderfactory factory = new pluginproviderfactory (configsource); pluginprovider provider = factory. Create (providerconfigname );

To create the provider object. If you do not need to use generics, the basic program block will be completed during runtime. Of course, the real provider has not yet implemented, that is, the implementation of the subclass of pluginprovider. To support generic and strong types, Some helper classes are also required.

7 Implementation of generic helper classes

Here, two helper classes are implemented: pluginmanager <t> to implement pluginprovider
Pluginmanagerfactory <t> implements the pluginproviderfactory
Class encapsulation. Because no special method is used in the implementation of these two classes, I will not explain it in detail here. Only the corresponding code is listed as follows:

    • Pluginmanager <t> class
Using system. collections;
Using system. Collections. Generic;
Namespace pluginloader
{
Public class pluginmanager <t>
{
Private pluginprovider _;

Internal pluginmanager (pluginprovider provider)
{
This. provider _ = provider;
}

Public ilist <t> getplugins ()
{
Ilist plugins = This. provider _. getplugins ();
List <t> returnlist = new list <t> (plugins. Count );
Foreach (T item in plugins)
{
Returnlist. Add (item );
}
Return returnlist;
}
}
}

    • Pluginmanagerfactory <t> class
Using system;
Using system. Collections. Generic;
Using system. text;
Using Microsoft. Practices. enterpriselibrary. Common. configuration;
Namespace pluginloader
{
Public class pluginmanagerfactory <t>
{
Private pluginproviderfactory factory _;
Public pluginmanagerfactory (iconfigurationsource configurationsource)
{
This. Factory _ = new pluginproviderfactory (configurationsource );
}
Public pluginmanager <t> Create ()
{
String name = typeof (T). assemblyqualifiedname;
Return new pluginmanager <t> (this. Factory _. Create (name ));
}
}
}

8. Client Interface

After the underlying layers are compiled, we need to provide a factory class for the client code to make the client more convenient to use, pluginfactory. Using Microsoft. Practices. enterpriselibrary. Common. configuration;
Using system;
Using system. Collections. Generic;
Using system. text;
Namespace pluginloader
{
Public static class pluginfactory
{
Private readonly static dictionary <type, Object> factories _ = new dictionary <type, Object> ();
Public static pluginmanager <t> getmanager <t> ()
{
If (! Factories _. containskey (typeof (t )))
{
Iconfigurationsource configsource = configurationsourcefactory. Create ();
Pluginmanagerfactory <t> factory = new pluginmanagerfactory <t> (configsource );
Factories _. Add (typeof (t), factory );
}
Object obfactory = factories _ [typeof (t)];
Return (pluginmanagerfactory <t>) obfactory). Create ();
}
}
}

The functions implemented here are described in the sample code at the end of section 6th.

9. Implement real plug-in providers

Similarly, implementing a real plug-in provider requires three steps:

    1. The configuration class is derived from pluginproviderdata;
    2. Inherit the pluginprovider class to implement real providers;
    3. Implements the icycler interface to provide a factory class for creating a real plug-in provider from the configuration class.
    4. Use the assumerattribute attribute class to bind the factory class to the configuration class, and use the configurationelementtypeattribute class to bind the configuration class to the provider class, so that the Enterprise Library can truly handle all this.

Here, the relevant code is no longer listed, interested friends can download the code (http://forum.entlib.net.cn/yaf_postst38_Enterprise-Library-.aspx) and follow the above steps to view.

At this point, we have created a complete application block. If you are willing to manually write the configuration file, you can configure it according to the scheme in section 3rd. Configure the corresponding plug-in provider in the add element. The name is arbitrary and does not need to be repeated. type is the type of the provider implemented in section 9th.

Next, we will explain how to create the design-time components of the above blocks so that we can use the Enterprise Library configuration console to configure them from the GUI.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.