Developing Application Frameworks in .Net--(Note2, Configuration/Class Factory)
2007-01-09 15:57
465 查看
Configuration / Remoting -----> Class Factory
[ Configuration in C# ]
COM components used the registry to configure components. Configuration of .NET applications is done by using configuration files. With registry configurations, an xcopy-deployment is not possible. The configuration files use XML syntax to specify startup and runtime settings for applications.
Startup settings
Runtime settings
Remoting settings
Security settings
....................... all are declared defaultly in < machine.config >
---- Application configuration files
[web.config] ---> for web application
[*.exe.config]--> for executable application <add app.config in startup project>
---- Machine configuration files
---- publisher policy files
<appSettings>
<add key = "DatabaseConnection" value = "Initial Catalog = Northwind; Data Source = localhost;"/>
</appSettings>
CLR affords:
System.Configuration.ConfigurationSettings.AppSettings["DatabaseConnection"];
All configuration information are read by implementation of IConfigurationSectionHandler which has only one method to override
object Create ( object parent, object configContext, XmlNode section)
object infor = ConfigurationSettings.GetConfig("sectionName1");
----- look for section named sectionName1
----- create handler object by type information with reflection mechanism
----- CLR call the create method of the object created just now
----- The third parameter XmlNode section contains the detail info of the section.
----- Parse the xml node and return an object
*** CLR only instantiate the handler once. ***
Four handler classes CLR affords:
System.Configuration.DictionarySectionHandler return Dictionary object, key/value
System.Configuration.IgnoreSectionHandler Ignore this type, return NULL
System.Configuration.NameValueSectionHandler return NameValueCollection object
System.Configuration.SingleTagSectionHandler retrun HashTable object, the data of attributes
<configSections>
<section name = "lunch" type = "System.Configuration.SingleTagSectionHandler, System">
</configSections>
....
<lunch soup = 'eggdrop' soda = 'coke' dish = 'beef'/>
....
HashTable luchInfo = (HashTable)ConfigurationSettings.GetConfig("lunch");
string soup = lunchInfo["soup"].ToString();
string soda = lunchInfo["soda "].ToString();
string dish = lunchInfo["dish"].ToString();
Encapsulate information and use Intellisense functionality
Handler class <Implement IConfigurationSectionHandler Interface>---> Configuration Manager class <constructor with XMLNode>----> configuration class <Property or Field to get settings>
public class ConfigurationHandler : System.Configuration.IConfigurationSectionHandler
...{
public object Create(Object parent, object configContext, XmlNode section)
...{
Type type = System.Type.GetType(section.Attributes["type"].Value);
object[] parameters = ...{section};
//call the configuration object's constructor
object configObject = null;
try
...{
configObject = Activator.CreateInstance(type, parameters);
}
catch (Exception ex)
...{
string x = ex.Message;
return null;
}
return configObject;
}
}
/**//// Provides access to configuraiton object for the framework component
public class ConfigurationManager
...{
public SAF.Configuration.ClassFactoryConfiguration ClassFactoryConfig;
private XmlNode configurationData;
/**//// Initialize all the configuration objects accessible through this configuration manager.
public ConfigurationManager (XmlNode sections)
...{
configurationData = sections;
ConfigurationAgentManager cam = new ConfigurationAgentManager(configurationData);
ClassFactoryConfig = new ClassFactoryConfiguration(cam.GetData("SAF.ClassFactory"));
}
}
public class ClassFactoryConfiguration
...{
private XmlNode classFactoryXml;
/**//// the constructor is called by the configuraiton manager
public ClassFactoryConfiguration(XmlNode configData)
...{
classFactoryXml = configData;
}
/**//// retrieve information about a class stored in the SAF.ClassFactory section
public XmlNode GetFactoryData(string name)
...{
return classFactoryXml.SelectSingleNode("Class[@name='" + name + "']");
}
}
The second purpose: Integeration setting --- Agent
public class ConfigurationAgentManager
...{
private XmlNode configurationData;
public ConfigurationAgentManager(XmlNode configData)...{
configurationData = configData;
}
/**//// it return the Xml containing the configuraiton settings for a given key
public XmlNode GetData(string key)...{
XmlNode result=null;
XmlAttribute agentAttribute =null;
if (configurationData.SelectSingleNode(key) != null)...{
//check if there is agent defined for a particular section or key
//if there is, load the agent and make it retrieve the data
//otherwise, just load the data from the configuraiton file
agentAttribute = configurationData.SelectSingleNode(key).Attributes["ConfigurationAgent"];
if ( agentAttribute == null) ...{
result = configurationData.SelectSingleNode(key);
} else ...{
//retrive the data using the agent
string data = GetAgent(agentAttribute.Value).GetConfigurationSetting();
XmlDocument xml = new XmlDocument();
xml.LoadXml(data);
result = (XmlNode)xml.DocumentElement;
}
}
return result;
}
/**//// the method load the agent using reflection and return an instance of agent to the caller
private IConfigurationAgent GetAgent(string agentName)...{
XmlNode agentNode = configurationData.SelectSingleNode("//Agent[@name ='" + agentName + "']");
Type type = Type.GetType(agentNode.Attributes["type"].Value);
IConfigurationAgent agent = (IConfigurationAgent)Activator.CreateInstance(type,null);
//Initialize method setup the agent object with the parameter information specified
//in the file that is needed for the agent to do its job
agent.Initialize(agentNode);
return agent;
}
}
/**//// Interface that each agent class must implement.its two methods are called by agent manager at runtime.
public interface IConfigurationAgent
...{
void Initialize(XmlNode xml);
string GetConfigurationSetting();
}
.Net Remoting
server activation
---- singleton
---- single call
client activation
<configuration>
<configSections>
<section name="Framework" type="SAF.Configuration.ConfigurationHandler,SAF.Configuration" />
<section name="MyApplication" type="SAF.Configuration.ConfigurationHandler,SAF.Configuration" />
</configSections>
<!--Remoting-->
<system.runtime.remoting>
<application>
<service>
<wellknown
mode="Singleton"
type="TestConcreteFactory.ConcreteRemoteProductFactory,TestConcreteFactory"
objectUri="ClassFactory.rem" />
</service>
<channels>
<channel ref="http" port="8989"/>
</channels>
</application>
</system.runtime.remoting>
<!--Class Factory-->
<Framework type="SAF.Configuration.ConfigurationManager,SAF.Configuration">
<SAF.ClassFactory> <Class name="ProductFactory-A" type="TestConcreteFactory.ConcreteProductFactory,TestConcreteFactory" /> <Class name="ProductFactory-B" type="TestConcreteFactory.ConcreteNewProductFactory,TestConcreteFactory" /> <Class name="Remote-ProductFactory-C" location="http://localhost:8989/ClassFactory.rem" type="TestConcreteFactory.ConcreteRemoteProductFactory,TestConcreteFactory" />
</SAF.ClassFactory>
</Framework>
<!--Agent--> <MyApplication type="Application.Configuration.AppConfigurationManager,Application.Configuration">
<Application.Configuration>
<ConfigurationAgent>
<Agent name = "WSAgent1" type="TestConfigurationAgent.ConfigurationWSAgent,TestConfigurationAgent">
<Parameters>
<Section>Application.MessageQueue</Section>
<Environment>QAEnvironment</Environment>
</Parameters>
<Url>http://localhost/ConfigurationData/ConfigurationService.asmx</Url>
</Agent>
</ConfigurationAgent>
</Application.Configuration>
</MyApplication>
</configuration>
Class Factory and Reflection
MyClass classA = new MyClass();
classA.DoWork();
using System.Reflection;
Assembly assm = Assembly.Load("TestApp");
Type objType = assm.GetType("TestApp.MyClass");
object objInstance = Activator.CreateInstance(objType);
objType.InvokeMember("DoWork", BindingFlags.InvokeMethod, null, objInstance, null);
public class ClassFactory
..{
private ClassFactory()...{}
/**//// Called by the client to get an instance of the factory class
public static object GetFactory(string factoryName)
...{
object factory = null;
ConfigurationManager cm = (ConfigurationManager)ConfigurationSettings.GetConfig("Framework");
ClassFactoryConfiguration cf= cm.ClassFactoryConfig;
XmlNode classFactoryData = cf.GetFactoryData(factoryName);
//obtain the type information
string type = classFactoryData.Attributes["type"].Value;
Type t = System.Type.GetType(type);
//creat an instance of concrete class factory
if (classFactoryData.Attributes["location"] != null)
...{
// Remoting
string location = classFactoryData.Attributes["location"].Value;
factory = Activator.GetObject(t,location);
}
else
...{
factory = Activator.CreateInstance(t,null);
}
return factory;
}
}
[ Configuration in C# ]
COM components used the registry to configure components. Configuration of .NET applications is done by using configuration files. With registry configurations, an xcopy-deployment is not possible. The configuration files use XML syntax to specify startup and runtime settings for applications.
Startup settings
Runtime settings
Remoting settings
Security settings
....................... all are declared defaultly in < machine.config >
---- Application configuration files
[web.config] ---> for web application
[*.exe.config]--> for executable application <add app.config in startup project>
---- Machine configuration files
---- publisher policy files
<appSettings>
<add key = "DatabaseConnection" value = "Initial Catalog = Northwind; Data Source = localhost;"/>
</appSettings>
CLR affords:
System.Configuration.ConfigurationSettings.AppSettings["DatabaseConnection"];
All configuration information are read by implementation of IConfigurationSectionHandler which has only one method to override
object Create ( object parent, object configContext, XmlNode section)
object infor = ConfigurationSettings.GetConfig("sectionName1");
----- look for section named sectionName1
----- create handler object by type information with reflection mechanism
----- CLR call the create method of the object created just now
----- The third parameter XmlNode section contains the detail info of the section.
----- Parse the xml node and return an object
*** CLR only instantiate the handler once. ***
Four handler classes CLR affords:
System.Configuration.DictionarySectionHandler return Dictionary object, key/value
System.Configuration.IgnoreSectionHandler Ignore this type, return NULL
System.Configuration.NameValueSectionHandler return NameValueCollection object
System.Configuration.SingleTagSectionHandler retrun HashTable object, the data of attributes
<configSections>
<section name = "lunch" type = "System.Configuration.SingleTagSectionHandler, System">
</configSections>
....
<lunch soup = 'eggdrop' soda = 'coke' dish = 'beef'/>
....
HashTable luchInfo = (HashTable)ConfigurationSettings.GetConfig("lunch");
string soup = lunchInfo["soup"].ToString();
string soda = lunchInfo["soda "].ToString();
string dish = lunchInfo["dish"].ToString();
Encapsulate information and use Intellisense functionality
Handler class <Implement IConfigurationSectionHandler Interface>---> Configuration Manager class <constructor with XMLNode>----> configuration class <Property or Field to get settings>
public class ConfigurationHandler : System.Configuration.IConfigurationSectionHandler
...{
public object Create(Object parent, object configContext, XmlNode section)
...{
Type type = System.Type.GetType(section.Attributes["type"].Value);
object[] parameters = ...{section};
//call the configuration object's constructor
object configObject = null;
try
...{
configObject = Activator.CreateInstance(type, parameters);
}
catch (Exception ex)
...{
string x = ex.Message;
return null;
}
return configObject;
}
}
/**//// Provides access to configuraiton object for the framework component
public class ConfigurationManager
...{
public SAF.Configuration.ClassFactoryConfiguration ClassFactoryConfig;
private XmlNode configurationData;
/**//// Initialize all the configuration objects accessible through this configuration manager.
public ConfigurationManager (XmlNode sections)
...{
configurationData = sections;
ConfigurationAgentManager cam = new ConfigurationAgentManager(configurationData);
ClassFactoryConfig = new ClassFactoryConfiguration(cam.GetData("SAF.ClassFactory"));
}
}
public class ClassFactoryConfiguration
...{
private XmlNode classFactoryXml;
/**//// the constructor is called by the configuraiton manager
public ClassFactoryConfiguration(XmlNode configData)
...{
classFactoryXml = configData;
}
/**//// retrieve information about a class stored in the SAF.ClassFactory section
public XmlNode GetFactoryData(string name)
...{
return classFactoryXml.SelectSingleNode("Class[@name='" + name + "']");
}
}
The second purpose: Integeration setting --- Agent
public class ConfigurationAgentManager
...{
private XmlNode configurationData;
public ConfigurationAgentManager(XmlNode configData)...{
configurationData = configData;
}
/**//// it return the Xml containing the configuraiton settings for a given key
public XmlNode GetData(string key)...{
XmlNode result=null;
XmlAttribute agentAttribute =null;
if (configurationData.SelectSingleNode(key) != null)...{
//check if there is agent defined for a particular section or key
//if there is, load the agent and make it retrieve the data
//otherwise, just load the data from the configuraiton file
agentAttribute = configurationData.SelectSingleNode(key).Attributes["ConfigurationAgent"];
if ( agentAttribute == null) ...{
result = configurationData.SelectSingleNode(key);
} else ...{
//retrive the data using the agent
string data = GetAgent(agentAttribute.Value).GetConfigurationSetting();
XmlDocument xml = new XmlDocument();
xml.LoadXml(data);
result = (XmlNode)xml.DocumentElement;
}
}
return result;
}
/**//// the method load the agent using reflection and return an instance of agent to the caller
private IConfigurationAgent GetAgent(string agentName)...{
XmlNode agentNode = configurationData.SelectSingleNode("//Agent[@name ='" + agentName + "']");
Type type = Type.GetType(agentNode.Attributes["type"].Value);
IConfigurationAgent agent = (IConfigurationAgent)Activator.CreateInstance(type,null);
//Initialize method setup the agent object with the parameter information specified
//in the file that is needed for the agent to do its job
agent.Initialize(agentNode);
return agent;
}
}
/**//// Interface that each agent class must implement.its two methods are called by agent manager at runtime.
public interface IConfigurationAgent
...{
void Initialize(XmlNode xml);
string GetConfigurationSetting();
}
.Net Remoting
server activation
---- singleton
---- single call
client activation
<configuration>
<configSections>
<section name="Framework" type="SAF.Configuration.ConfigurationHandler,SAF.Configuration" />
<section name="MyApplication" type="SAF.Configuration.ConfigurationHandler,SAF.Configuration" />
</configSections>
<!--Remoting-->
<system.runtime.remoting>
<application>
<service>
<wellknown
mode="Singleton"
type="TestConcreteFactory.ConcreteRemoteProductFactory,TestConcreteFactory"
objectUri="ClassFactory.rem" />
</service>
<channels>
<channel ref="http" port="8989"/>
</channels>
</application>
</system.runtime.remoting>
<!--Class Factory-->
<Framework type="SAF.Configuration.ConfigurationManager,SAF.Configuration">
<SAF.ClassFactory> <Class name="ProductFactory-A" type="TestConcreteFactory.ConcreteProductFactory,TestConcreteFactory" /> <Class name="ProductFactory-B" type="TestConcreteFactory.ConcreteNewProductFactory,TestConcreteFactory" /> <Class name="Remote-ProductFactory-C" location="http://localhost:8989/ClassFactory.rem" type="TestConcreteFactory.ConcreteRemoteProductFactory,TestConcreteFactory" />
</SAF.ClassFactory>
</Framework>
<!--Agent--> <MyApplication type="Application.Configuration.AppConfigurationManager,Application.Configuration">
<Application.Configuration>
<ConfigurationAgent>
<Agent name = "WSAgent1" type="TestConfigurationAgent.ConfigurationWSAgent,TestConfigurationAgent">
<Parameters>
<Section>Application.MessageQueue</Section>
<Environment>QAEnvironment</Environment>
</Parameters>
<Url>http://localhost/ConfigurationData/ConfigurationService.asmx</Url>
</Agent>
</ConfigurationAgent>
</Application.Configuration>
</MyApplication>
</configuration>
Class Factory and Reflection
MyClass classA = new MyClass();
classA.DoWork();
using System.Reflection;
Assembly assm = Assembly.Load("TestApp");
Type objType = assm.GetType("TestApp.MyClass");
object objInstance = Activator.CreateInstance(objType);
objType.InvokeMember("DoWork", BindingFlags.InvokeMethod, null, objInstance, null);
public class ClassFactory
..{
private ClassFactory()...{}
/**//// Called by the client to get an instance of the factory class
public static object GetFactory(string factoryName)
...{
object factory = null;
ConfigurationManager cm = (ConfigurationManager)ConfigurationSettings.GetConfig("Framework");
ClassFactoryConfiguration cf= cm.ClassFactoryConfig;
XmlNode classFactoryData = cf.GetFactoryData(factoryName);
//obtain the type information
string type = classFactoryData.Attributes["type"].Value;
Type t = System.Type.GetType(type);
//creat an instance of concrete class factory
if (classFactoryData.Attributes["location"] != null)
...{
// Remoting
string location = classFactoryData.Attributes["location"].Value;
factory = Activator.GetObject(t,location);
}
else
...{
factory = Activator.CreateInstance(t,null);
}
return factory;
}
}
相关文章推荐
- Developing Application Frameworks in .NET(隨書源碼下載地址)
- Developing Application Frameworks in .Net --- (Note 3 Cach)
- Developing Application Frameworks in .Net ---- (Note1, Landscape)
- Developing Application Frameworks in .Net
- Developing Application Frameworks in .NET
- Error creating bean with name 'mySessionFactory' defined in class path resource [applicationContext.xml]:
- Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xm
- Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xm
- Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xm
- Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xm
- Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xm
- Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xm
- Error creating bean with name 'sessionFactory' defined in class path resource [spring/applicationCon
- Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.init
- Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xm
- Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xm
- 解决错误Error creating bean with name 'MySessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init
- Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xm
- Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xm
- Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xm