now i am assigned to web project,that used asp.net mvc with c#.
i need to load some XML file like below and that will tell which controls i need to create.
This also tells,type of controls,their value,size and location.i can't find the way how i do?please guide me right way.
<Object type="System.Windows.Forms.Form" name="frmShow" >
<Object type="System.Windows.Forms.RadioButton" name="optOne">
<Property name="Size">86, 24</Property>
<Property name="Text">Option1</Property>
<Property name="Location">175, 126</Property>
</Object>
<Object type="System.Windows.Forms.CheckBox" name="chkOne">
<Property name="Size">84, 24</Property>
<Property name="Text">CheckOne</Property>
<Property name="Location">84, 126</Property>
</Object>
<Object type="System.Windows.Forms.TextBox" name="txtOne">
<Property name="Size">177, 20</Property>
<Property name="Text">ABC</Property>
<Property name="Location">84, 88</Property>
</Object>
<Object type="System.Windows.Forms.Label" name="lblOne">
<Property name="Size">100, 23</Property>
<Property name="Text">Name</Property>
<Property name="Location">8, 91</Property>
</Object>
<Object type="System.Windows.Forms.TextBox" name="txtTwo">
<Property name="Size">177, 20</Property>
<Property name="Text">Home Address</Property>
<Property name="Location">84, 50</Property>
</Object>
<Object type="System.Windows.Forms.Label" name="lblTwo">
<Property name="Size">100, 23</Property>
<Property name="Text">Address</Property>
<Property name="Location">7, 53</Property>
</Object>
<ItemDataSet>
<ItemTable>
<TableName>tblItemOne</TableName>
<Row1>
<Repeat>True</Repeat>
<ItemName>Item001</ItemName>
<Qty>10</Qty>
<Price>1000</Price>
</Row1>
<Row2>
<Repeat>True</Repeat>
<ItemName>Item002</ItemName>
<Qty>20</Qty>
<Price>2000</Price>
</Row2>
<Row3>
<Repeat>false</Repeat>
<ItemName>Item003</ItemName>
<Qty>30</Qty>
<Price>3000</Price>
</Row3>
</ItemTable>
</ItemDataSet>
</Object>
This code creates a dictionary of controls. You can optimize it further if you need.
Another alternative is to create a schema (xsd) based on the xml and then use XmlSerializer as suggested by #Jon Abaca. The XmlSerializer option is much simpler than this approach.
First approach (without XmlSerializer)
private Dictionary GetControlDictionary(string xmlFilePath)
{
Dictionary controlsDictionary = new Dictionary();
Assembly assembly = Assembly.GetAssembly(typeof(System.Windows.Forms.Form));
using (XmlReader xmlReader = XmlReader.Create(xmlFilePath))
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(xmlReader);
XmlNodeList xmlNodesList = xmlDocument.SelectNodes("//Object");
foreach (XmlNode xmlNode in xmlNodesList)
{
if (xmlNode.Attributes.Count > 0)
{
string typeName = xmlNode.Attributes["type"].Value;
string objectName = xmlNode.Attributes["name"].Value;
Type controlType = assembly.GetType(typeName);
if (controlType != null)
{
object controlObject = Activator.CreateInstance(controlType);
if (controlObject is Control)
{
Control control = controlObject as Control;
control.Name = objectName;
controlsDictionary.Add(objectName, control);
foreach (XmlNode childNode in xmlNode.ChildNodes)
{
if (string.Equals("Property", childNode.Name))
{
string propertyName = childNode.Attributes["name"].Value;
string propertyValue = childNode.InnerText;
PropertyInfo propertyInfo = controlType.GetProperty(propertyName);
if (propertyInfo != null)
{
if(propertyInfo.PropertyType == typeof(System.Drawing.Size))
{
string width = propertyValue.Split(new char[] {','})[0];
string height = propertyValue.Split(new char[] {','})[1];
System.Drawing.Size size = new Size(Convert.ToInt32(width), Convert.ToInt32(height));
propertyInfo.SetValue(control, size, null);
}
else if(propertyInfo.PropertyType == typeof(System.Drawing.Point))
{
string x = propertyValue.Split(new char[] { ',' })[0];
string y = propertyValue.Split(new char[] { ',' })[0]; System.Drawing.Point point = new Point(Convert.ToInt32(x), Convert.ToInt32(y));
propertyInfo.SetValue(control, point, null);
}
else if (propertyInfo.PropertyType == typeof(string))
{
propertyInfo.SetValue(control, propertyValue, null);
}
}
}
}
}
}
}
}
}
return controlsDictionary;
}
Try to convert this scala code for C# or even you can consume the Scale in c# Refer to http://code.google.com/p/xsd-forms/
Also you can use XSLTViewEngine
XSD Form built based on Scala
Related
Does anybody know why the following code doesn't find any Descendants named "PntList3D" in the XDocument? I've run similar code with xml files from different sources and it's worked just fine.
XDocument xdoc = XDocument.Load(file);
foreach (XElement pntList3D in xdoc.Descendants("PntList3D"))
{
//No XElements found?
string[] coords = pntList3D.Value.Split(separator);
//........
}
The XML file is as follows:
<?xml version="1.0" encoding="iso-8859-1" ?>
<LandXML xmlns="http://www.landxml.org/schema/LandXML-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.landxml.org/schema/LandXML-1.0 http://www.landxml.org/schema/landxml-1.0/LandXML-1.0.xsd" version="1.0" date="2018-05-21" time="10:54:45">
<Units>
<Metric areaUnit="squareMeter" linearUnit="meter" volumeUnit="cubicMeter" temperatureUnit="celsius" pressureUnit="HPA" angularUnit="radians" directionUnit="radians"/>
</Units>
<Application name="Bentley Rail Track V8i (SELECTseries 4)" manufacturer="Bentley Systems, Inc." version="08.11.09.878" manufacturerURL="www.bentley.com"/>
<Surfaces>
<Surface name="GUCanalFinalGround" state="proposed">
<SourceData>
<Breaklines>
<Breakline brkType="standard" name="Merge Boundary Breakline13">
<PntList3D>
373369.843784061 201940.481405058 100.010000000 373346.803045009 201978.937591557 100.266579521 373345.131682429 201986.094864832 100.285820869 373344.675829289 201994.051291911 100.305094741 373343.948058537 202002.377250983 100.325783280 373347.097559184 202015.927410062 100.351677422 373349.064121068 202028.461854698 100.377340245 373349.158000706 202037.105375695 100.397451931 373349.558848160 202047.019625644 100.420035342 373351.626002592 202059.961277642 100.444814507 373351.012091134 202068.660831945 100.465852191 373341.758274428 202103.172391947 100.582514748 373319.443256788 202115.548623449 100.621330067 373314.187088077 202116.429655954 100.632560880 373309.015283797 202117.464532283 100.644344390 373296.621004758 202116.103443765 100.663523942 373291.562007714 202117.732947895 100.675479985 373281.143675082 202119.484060498 100.698356878 373276.337524008 202120.933216769 100.710662078 373272.233432380 202123.836471532 100.724192638 373261.827555133 202125.960550682 100.747355849 373251.520869727 202128.251385445 100.770700659 373245.559103071 202128.214153277 100.781125221 373239.789665844 202128.349784236 100.791427303 373229.601950129 202130.619067512 100.814814992 373225.304350337 202132.986580328 100.828137161 373214.890815224 202136.688095193 100.839157834 373210.210442728 202138.686367756 100.852302328 373204.606106857 202142.207609670 100.866054658 373191.545497214 202148.081237003 100.918005418 373176.562316984 202152.361356766 100.954250454 373171.044645747 202154.053893695 100.966278732 373166.208397576 202155.713237010 100.978687738 373160.708995109 202155.679722689 100.989287494 373155.688534545 202156.493295914 101.000834112 373150.482235484 202157.176413548 101.012161143 373144.212549179 202156.159209438 101.021467326 373137.448440098 202156.600718164 101.031754759 373131.391817655 202156.182136957 101.041765542 373125.390422036 202155.709761447 101.051750480 373119.276552408 202155.069671573 101.061523722 373054.430807066 202143.721890221 102.441500000 373058.442814638 202140.697787490 102.328000000 373066.166069761 202134.158949750 101.933000000 373073.565553867 202127.092819841 101.360000000 373080.608667856 202119.447463058 100.589000000 373087.692942040 202111.870287954 99.839000000 373091.238928264 202108.087310204 99.465000000 373092.286790268 202109.791671688 99.504983646 373095.832728759 202106.008743033 99.130988179 373102.878820288 202098.368395826 98.353988013 373110.583835192 202091.800057704 97.934987722 373118.123075009 202084.962016843 97.421992176 373125.392085793 202077.684336252 96.759009538 373132.990746979 202070.942967185 96.274010799 373140.640127087 202064.284112116 95.814017469 373150.541354297 202061.288814036 96.578880626 373155.592889845 202050.403490658 94.696924444 373161.444949212 202040.820548117 93.249013491 373170.040905925 202035.701685379 93.293999781 373178.501762418 202030.363025321 93.264000224 373187.026261039 202025.127904379 93.265000042 373195.553374235 202019.897036065 93.265999882 373204.080773941 202014.666632815 93.264000015 373212.683146019 202009.558202046 93.299998484 373221.146334288 202004.223330229 93.258000145 373229.732436104 201999.088427042 93.279999413 373238.278154811 201993.887822981 93.277999879 373246.827935106 201988.693825711 93.275000301 373255.419702686 201983.568137077 93.292999519 373270.410218672 201988.852661245 96.796999371 373278.832148334 201983.450659530 96.717001898 373287.478398532 201978.413607052 96.756999575 373296.854035216 201974.563203038 97.191991671 373306.521867266 201971.188175126 97.782985073 373316.068961675 201967.616716606 98.305980919 373325.538253354 201963.918678862 98.785012746 373334.774518673 201959.841526182 99.132990669 373333.727060669 201958.136888591 99.093000000 373342.581640977 201953.439507703 99.231000000 373351.873048413 201949.452662854 99.604000000 373360.885734860 201945.010817605 99.823000000 373369.843784061 201940.481405058 100.010000000
</PntList3D>
<Feature code="Breakline">
<Property label="guid" value="210f4f9d-6f98-4246-8967-4b11eb616339"/>
<Property label="style" value="Default"/>
<Property label="triangulate" value="true"/>
<Property label="pointDensity" value="0.000000000"/>
</Feature>
</Breakline>
<Breakline brkType="standard" name="DB75">
<PntList3D>
373095.450629438 202114.938959557 101.014871165 373092.286790268 202109.791671688 99.504983646
</PntList3D>
<Feature code="Breakline">
<Property label="guid" value="9d937eeb-bcf1-4d51-97c1-080736d60adb"/>
<Property label="style" value="Default"/>
<Property label="triangulate" value="true"/>
<Property label="pointDensity" value="0.000000000"/>
</Feature>
</Breakline>
<Breakline brkType="standard" name="DB74">
<PntList3D>
373054.430807066 202143.721890221 102.441500000 373095.450629438 202114.938959557 101.014871165
</PntList3D>
<Feature code="Breakline">
<Property label="guid" value="71b6272a-99f3-483c-b997-4b3b82de6984"/>
<Property label="style" value="Default"/>
<Property label="triangulate" value="true"/>
<Property label="pointDensity" value="0.000000000"/>
</Feature>
</Breakline>
</Breaklines>
</SourceData>
</Surface>
</Surfaces>
</LandXML>
I couldn't submit this question as apparently I had too much code and not enough detail. I'm pretty sure the amount of detail I provided was adequate so the following text is just to get this question through the Stackoverflow Bots.
Please try the following approach.
The entire XML is bound to a default namespace.
First, you need to get a default namespace just once.
Second, use it any time while referring to the XML element names.
c#
void Main()
{
const string FILENAME = #"e:\Temp\LandXML.xml";
XDocument xdoc = XDocument.Load(FILENAME);
XNamespace ns = xdoc.Root.GetDefaultNamespace();
foreach (XElement pntList3D in xdoc.Descendants(ns + "PntList3D"))
{
Console.WriteLine(pntList3D.Value + Environment.NewLine);
}
}
You need to specify the namespace in your call for Descendants:
foreach (var pntList3D in xdoc.Descendants(XName.Get("PntList3D","http://www.landxml.org/schema/LandXML-1.0")))
{
//No XElements found?
string[] coords = pntList3D.Value.Split(separator);
//........
}
I am trying to edit a existing XML file through C# and need to identify the sections I want (block name="treeDeadTree01" and block name="treeDeadTree02") Then get the value of "count" in the child element "drop". I have been able to identify the elements (block name="treeDeadTree01" and block name="treeDeadTree02") but cant figure out how to get the value of "count" from the element "drop" of the specific elements (block name="treeDeadTree01" and block name="treeDeadTree02")
The XML file is a config file from the game 7 Days To Die and I am trying to make a application to more easily edit the configs of the game. After I find the value of "count" I am putting it into a DataGridView.
My question is, how after I find the block element I want do I find the value of "count" in the "drop" child element of the block element?
This is a section of the XML file I am trying to edit
<blocks>
<block name="treeDeadTree01">
<property name="Extends" value="treeMaster" />
<property name="Model" value="Entities/Trees/White_Oak22Prefab" />
<property name="ModelOffset" value="0,-0.3,0" />
<property name="MultiBlockDim" value="1,4,1" />
<property name="BigDecorationRadius" value="4" />
<property name="Collide" value="movement,melee,bullet,arrow,rocket" />
<drop event="Harvest" name="resourceWood" count="515" tag="oreWoodHarvest" />
<property name="ParticleOnDeath" value="treeGib_dead_01" />
<!-- <drop event="Destroy" name="treePlantedMaple1m" count="x"/> -->
<property name="SortOrder2" value="0140" />
<!-- SortTree -->
</block>
<block name="treeDeadTree02">
<!-- almost a shrub -->
<property name="Extends" value="treeMaster" />
<property name="IsTerrainDecoration" value="true" />
<property name="Model" value="Entities/Trees/Haunted_Shrub_WastelandPrefab" />
<property name="ModelOffset" value="0,-0.3,0" />
<property name="Collide" value="melee,rocket" />
<!-- no movement effect on Shape="ModelTree" -->
<drop event="Harvest" name="resourceWood" count="215" tag="oreWoodHarvest" />
<property name="ParticleOnDeath" value="treeGib_dead_02" />
<!-- <drop event="Destroy" name="treePlantedMaple1m" count="x"/> -->
<property name="FilterTags" value="foutdoor,ftrees,fshrubbery" />
<property name="SortOrder1" value="a060" />
</block>
</blocks
My current code
string[] GatherRateNames = {"treeDeadTree01", "treeDeadTree02"};
string XMLBlocksPath = "F:\\SteamLibrary\\steamapps\\common\\7 Days To Die\\Data\\Config\\blocks.xml";
private void makeGatherRatesList()
{
XmlDocument doc = new XmlDocument();
doc.Load(XMLBlocksPath);
XmlNodeList aNodes = doc.SelectNodes("/blocks/block");
foreach (XmlNode aNode in aNodes)
{
XmlAttribute idAttribute = aNode.Attributes["name"];
if (GatherRateNames.Contains(idAttribute.ToString()))
{
addItemToList(idAttribute.ToString(),"Value of count");
}
}
}
private void addItemToList(string itemName, int itemValue)
{
}
In the end I want to get the name of the block like "treeDeadTree01" then get the value of "count" inside the element "drop" of that block and put both of those in a DataGridView and be able to edit the value of count through the DataGridView then repeat that with every block I need.
Using Xml Linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Globalization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
CultureInfo culture = (CultureInfo)CultureInfo.InvariantCulture.Clone();
culture.NumberFormat.NumberDecimalSeparator = ",";
culture.NumberFormat.NumberGroupSeparator = ".";
XmlReader reader = XmlReader.Create(FILENAME);
List<Block> blocks = new List<Block>();
while (!reader.EOF)
{
if (reader.Name != "block")
{
reader.ReadToFollowing("block");
}
if (!reader.EOF)
{
Block newBlock = new Block();
blocks.Add(newBlock);
XElement xBlock = (XElement)XElement.ReadFrom(reader);
newBlock.name = (string)xBlock.Attribute("name");
XElement drop = xBlock.Element("drop");
if (drop != null)
{
object count = drop.Attribute("count");
newBlock.count = (count == null)? null : (decimal?)decimal.Parse((string)count, culture);
}
}
}
}
public class Block
{
public string name { get; set; }
public decimal? count { get; set; }
}
}
}
I need to change password values in my configuration.xml .
Password need to be changed for following users :
tsuer1
github
wtsntro
wtsntrw and so on.
Format of configuration.xml file is like following :
<?xml version="1.0" encoding="UTF-8"?>
<server xmlns="urn:jboss:domain:1.2">
<extensions>
<extension module="org.jboss.as.clustering.infinispan" />
<extension module="org.jboss.as.cmp" />
<extension module="org.jboss.as.ejb3" />
</extensions>
<system-properties>
<property name="SERVER" value="JBOSS" />
<property name="FTP_USER" value="adobenet\wtsntrw" />
<property name="FTP_PASSWORD" value="password value" />
<property name="FTP_READ_USER" value="adobenet\\wtsntro" />
<property name="FTP_READ_PASS" value="password value" />
<property name="API_SECRET_KEY" value="wxrocks" />
<property name="API_ENV" value="regular" />
<property name="PRERELEASE_PASSWORD" value="prerelease" />
<property name="watson.git_user" value="github" />
<property name="watson.git_pwd" value="password value" />
<property name="teststudio.user" value="tsuser1" />
<property name="teststudio.pwd" value="password value" />
</system-properties>
</server>
And following is the code i tried but failed :
XmlDocument doc = new XmlDocument();
string path = #"C:\Users\karansha\Desktop\configuration.xml"; // location of configuration.xml file.
doc.Load(path);
// Using foreach loop for specific Xmlnodes.
foreach (XmlNode selectNode in doc.SelectNodes("server/system-properties/property"))
{
if (selectNode.Attributes["name"].Value == "teststudio.pwd") // tsuser1
{
selectNode.Attributes["value"].Value = "new password"; // changes password value for "FTP_USER".
}
if (selectNode.Attributes["name"].Value == "watson.git_pwd") //github
{
selectNode.Attributes["value"].Value = "new passwordx"; // changes password value for "FTP_READ_USER".
}
if (selectNode.Attributes["name"].Value == "FTP_READ_PASS") // wtsntro
{
selectNode.Attributes["value"].Value = "new_passwordy"; // changes password value for "FTP_PASSWORD".
}
}
doc.Save(path); // Save changes.
Console.WriteLine("Password changed successfully");
Console.ReadLine();
Your Xml elements are contained in a NameSpace, so your XPath needs to account for that.
See:
XPath on an XML document with namespace
XML Namespaces and How They Affect XPath and XSLT
XmlDocument doc = new XmlDocument();
doc.Load(path);
var nm = new XmlNamespaceManager(doc.NameTable);
nm.AddNamespace("jb", "urn:jboss:domain:1.2");
foreach (XmlNode selectNode in doc.SelectNodes("jb:server/jb:system-properties/jb:property", nm))
{
if (selectNode.Attributes["name"].Value == "teststudio.pwd") // tsuser1
{
selectNode.Attributes["value"].Value = "new password"; // changes password value for "FTP_USER".
}
if (selectNode.Attributes["name"].Value == "watson.git_pwd") //github
{
selectNode.Attributes["value"].Value = "new passwordx"; // changes password value for "FTP_READ_USER".
}
if (selectNode.Attributes["name"].Value == "FTP_READ_PASS") // wtsntro
{
selectNode.Attributes["value"].Value = "new_passwordy"; // changes password value for "FTP_PASSWORD".
}
}
doc.Save(path); // Save changes.
Console.WriteLine("Password changed successfully");
You have to specify the namespace:
var nm = new XmlNamespaceManager(doc.NameTable);
if (doc.ChildNodes.Count != 2)
throw new XmlException("Document is not well formated.");
var serverNode = doc.ChildNodes[1];
nm.AddNamespace("a", serverNode.NamespaceURI);
foreach (XmlNode selectNode in
doc.SelectNodes("a:server/a:system-properties/a:property", nm))
{
// ...
}
How can I configure NHibernate to connect to both a MySQLserver and a Microsoft SQL server 2008? I do want to copy data from one server to another. I heard of NHibernate shared.
I've struggled quite a bit few months ago.
My problem was with MS Sql Server and Oracle.
What I've done is to create two separate config files for nhibernate:
sql.nhibernate.config
<?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<reflection-optimizer use="false" />
<session-factory name="BpSpedizioni.MsSql">
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
<!-- <property name="connection.connection_string">Data Source=(local); Initial Catalog=NHibernate; Trusted_Connection=true;</property> -->
<property name="current_session_context_class">web</property>
<property name="adonet.batch_size">100</property>
<property name="command_timeout">120</property>
<property name="max_fetch_depth">3</property>
<property name='prepare_sql'>true</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<mapping assembly="BpSpedizioni.Services"/>
</session-factory>
</hibernate-configuration>
ora.nhibernate.config
<?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<reflection-optimizer use="false" />
<session-factory name="BpSpedizioni.Oracle">
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property>
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
<!-- <property name="connection.connection_string">Data Source=(local); Initial Catalog=NHibernate; Trusted_Connection=true;</property> -->
<property name="current_session_context_class">web</property>
<property name="adonet.batch_size">100</property>
<property name="command_timeout">120</property>
<property name="max_fetch_depth">3</property>
<property name='prepare_sql'>true</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name='proxyfactory.factory_class'>NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<mapping assembly="BpSpedizioni.Services"/>
</session-factory>
</hibernate-configuration>
I use this simple class to build my nhibernate SessionFactory:
public class NHibernateSessionFactory
{
private ISessionFactory sessionFactory;
private readonly string ConnectionString = "";
private readonly string nHibernateConfigFile = "";
public NHibernateSessionFactory(String connectionString, string nHConfigFile)
{
this.ConnectionString = connectionString;
this.nHibernateConfigFile = nHConfigFile;
}
public ISessionFactory SessionFactory
{
get { return sessionFactory ?? (sessionFactory = CreateSessionFactory()); }
}
private ISessionFactory CreateSessionFactory()
{
Configuration cfg;
cfg = new Configuration().Configure(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, this.nHibernateConfigFile));
// With this row below Nhibernate searches for the connection string inside the App.Config.
// cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionStringName, System.Environment.MachineName);
cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionString, this.ConnectionString);
#if DEBUG
cfg.SetProperty(NHibernate.Cfg.Environment.GenerateStatistics, "true");
cfg.SetProperty(NHibernate.Cfg.Environment.ShowSql, "true");
#endif
return (cfg.BuildSessionFactory());
}
}
As you can see I pass to my NHibernateSessionFactory a connection string (I prefer to save it in my app config file) and the name (without the path) of the nhibernate config file.
I personally use a DI container (StructureMap) and you can achieve something very cool defining a registry class:
public class NhibernateRegistry : Registry
{
public NhibernateRegistry()
{
For<ISessionFactory>()
.Singleton()
.Add(new NHibernateSessionFactory(<oracle connection string>, "ora.nhibernate.config").SessionFactory)
.Named("OracleSF");
For<ISession>()
.HybridHttpOrThreadLocalScoped()
.Add(o => o.GetInstance<ISessionFactory>("OracleSF").OpenSession())
.Named("OracleSession");
For<ISessionFactory>()
.Singleton()
.Add(new NHibernateSessionFactory(<ms sql connection string>, "sql.nhibernate.config").SessionFactory)
.Named("MsSqlSF");
For<ISession>()
.HybridHttpOrThreadLocalScoped()
.Add(o => o.GetInstance<ISessionFactory>("MsSqlSF").OpenSession())
.Named("MsSqlSession");
}
}
in which you can use named instances.
My services layer than uses a StructureMap registry class where you can define the constructors:
this.For<IOrdersService>()
.HybridHttpOrThreadLocalScoped()
.Use<OrdersService>()
.Ctor<ISession>("sessionMDII").Is(x => x.TheInstanceNamed("OracleSession"))
.Ctor<ISession>("sessionSpedizioni").Is(x => x.TheInstanceNamed("MsSqlSession"));
For your Service implementation:
public class OrdersService : IOrdersService
{
private readonly ISession SessionMDII;
private readonly ISession SessionSpedizioni;
public OrdersService(ISession sessionMDII, ISession sessionSpedizioni)
{
this.SessionMDII = sessionMDII;
this.SessionSpedizioni = sessionSpedizioni;
}
...
}
It's not clear what your use case is, but you will simply need to create 2 session factories. One will use your mySQL dialect, connection string, etc... and the other will use the SQL Server equivalents.
Just avoid including any custom SQL in your mappings and this should work fine.
Here's the code raising the exception:
public static class NHibernateSessionManager
{
private static ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory();
public static ISession GetSession(string clientId)
{
if (ContextSession == null)
ContextSession = sessionFactory.OpenSession(new OracleIntercerptor(clientId.ToUpper()));
else
((OracleConnection)ContextSession.Connection).ClientId = clientId;
return ContextSession;
}
// - snip -
}
and the call to the code where the exception is raised:
private ISession NHibernateSession
{
get
{
return NHibernateSessionManager.GetSession(SessionWrapper.GetUser());
}
}
I get a TypeInitializationException
{"The type initializer for
'Sigaf.Presupuesto.EntidadesDAL.NHibernate.NHibernateSessionManager'
threw an exception."}
With an inner exception of
{"Could not create the driver from
NHibernate.Driver.OracleDataClientDriver."}
A few more inner exceptions lead me to a NRE:
Object reference not set to an
instance of an object.
at
NHibernate.Driver.OracleDataClientDriver..ctor()
NHibernate v3.0
Target Framework v4.0
This code implementation is working for other, similar, solutions.
Oh, the Hibernate.config file:
<?xml version="1.0"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
<property name="current_session_context_class">web</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
<property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property>
<property name="connection.connection_string_name">Sigaf</property>
<property name="default_schema">PRE</property>
<property name="show_sql">true</property>
<mapping assembly="Sigaf.Presupuesto.EntidadesDAL" />
</session-factory>
</hibernate-configuration>
Make sure the actual Oracle driver is in your application bin folder.
In Visual Studio you should add a reference to Oracle.DataAcess.dll in your project for example.
Select the DLL => Right click it => In the Properties grid select Copy Local = True.
This should solve your problem.