| 3/16/2006 3:15:18 AM |
I am using partial nested classes. I have a class called 'Server' and a nested class in that called 'Connection'. I am using paritial classes so that I can break it out into two files. I am nesting the class because Connection has a different meaning to other classes in the same namespace.
I can't seem to get WORM to load the nested type, however if I un-nest the 'Connection' type, it works just fine. Here is the error I get:
Initialization method Control4.Web.RemoteAccess.Servers.Tests.ConnectionManagerTest.TestInitialize threw exception. System.TypeInitializationException: System.TypeInitializationException: The type initializer for 'Control4.Web.RemoteAccess.Data' threw an exception. ---> Control4.Web.ORMapper.ORMapperException: ORMapper: Type could not be located in any loaded assembly - Control4.Web.RemoteAccess.Server.Connection.
Here is my code:
Server.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using Control4.Web.ORMapper;
using Control4.Web.Exceptions;
namespace Control4.Web.RemoteAccess
{
[ Serializable]
public partial class Server
{
#region - Fields and Constants -
private static int nextServerIndex = -1;
private static object nextServerLock = new object();
#endregion
#region - Constructors and Destructors -
private Server() { }
public Server(string address, string serviceUrl)
{
if (Server.Exists(address))
throw new ValidationException("The specified remote access server cannot be added because it already exists.");
this.Address = address;
this.ServiceUrl = serviceUrl;
Data.Manager.StartTracking(this, InitialState.Inserted);
}
#endregion
#region - Properties -
private int _Id = 0;
public int Id
{
get { return _Id; }
}
private string _Address;
public string Address
{
get { return _Address; }
set { _Address = value; }
}
private string _ServiceUrl;
public string ServiceUrl
{
get { return _ServiceUrl; }
set { _ServiceUrl = value; }
}
private Collection<Connection> _Connections;
public Collection<Connection> Connections
{
get
{
if (_Connections == null)
_Connections = new Collection<Connection>();
return _Connections;
}
}
#endregion
#region - Static Methods -
public static void ClearAll()
{
Collection<Server> Servers = GetAll();
Data.Manager.MarkForDeletion(Servers);
Data.Manager.PersistChanges(Servers);
}
public static int Count
{
get { return Data.Manager.GetObjectCount<Server>(""); }
}
public static Server Create(string address, string serviceUrl)
{
Server Server = new Server(address, serviceUrl);
Server.Save(Server);
return Server;
}
public static bool Exists(string address)
{
return (Data.Manager.GetObjectCount<Server>("Address = ?", address) > 0);
}
public static Server Find(string address)
{
return Data.Manager.GetObject<Server>(new OPathQuery<Server>("Address == ?"), address);
}
public static Collection<Server> GetAll()
{
return Data.Manager.GetCollection<Server>("");
}
/// <summary>
/// Returns the address of the next available remote access server.
/// </summary>
/// <returns></returns>
public static Server GetNextAvailable()
{
Collection<Server> Servers = GetAll();
lock (nextServerLock)
{
nextServerIndex++;
if (nextServerIndex >= Servers.Count)
nextServerIndex = 0;
}
return Servers[nextServerIndex];
}
public static void Save(Server server)
{
Data.Manager.PersistChanges(server, PersistDepth.ObjectGraph);
}
#endregion
}
}
Server.Connection.cs
using System;
using System.Xml.Serialization;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text;
using Control4.Web.ORMapper;
using Control4.Web.Exceptions;
namespace Control4.Web.RemoteAccess
{
public partial class Server
{
/// <summary>
/// Holds information for a connection to a remote access server.
/// </summary>
public class Connection
{
#region - Constructors and Destructors -
private Connection() { }
public Connection(string serverAddress, string account, string controllerUuid, string controllerAddress)
{
if (!Server.Exists(serverAddress))
throw new ValidationException("The specified remote access server does not exist.");
Server ConnectionServer = Server.Find(serverAddress);
Data.Manager.StartTracking(this, InitialState.Inserted);
this.Server = ConnectionServer;
this.ServerId = ConnectionServer.Id;
this.Account = account;
this.ControllerUuid = controllerUuid;
this.ControllerAddress = controllerAddress;
}
#endregion
#region - Properties -
private int _Id = 0;
internal int Id
{
get { return _Id; }
}
private string _Account;
public string Account
{
get { return _Account; }
set { _Account = value; }
}
private string _ControllerUuid;
public string ControllerUuid
{
get { return _ControllerUuid; }
set { _ControllerUuid = value; }
}
private string _ControllerAddress;
public string ControllerAddress
{
get { return _ControllerAddress; }
set { _ControllerAddress = value; }
}
private int _ServerId = 0;
internal int ServerId
{
get { return _ServerId; }
private set { _ServerId = value; }
}
private ObjectHolder<Server> _Server = null;
public Server Server
{
get { return _Server.InnerObject; }
private set { _Server.InnerObject = value; }
}
#endregion
/// <summary>
/// Removes all connections from the connection list.
/// </summary>
public static void ClearAll()
{
Collection<Connection> Connections = GetAll();
Data.Manager.MarkForDeletion(Connections);
Data.Manager.PersistChanges(Connections);
}
/// <summary>
/// Returns the number of connections in the connection list.
/// </summary>
public static int Count
{
get { return Data.Manager.GetObjectCount<Connection>("(0 = 0)"); }
}
public static Connection Create(string serverAddress, string account, string controllerUuid, string controllerAddress)
{
Connection Connection = new Connection(serverAddress, account, controllerUuid, controllerAddress);
Connection.Save(Connection);
return Connection;
}
/// <summary>
/// Verifies that the specified account is currently connected to a VPN server.
/// </summary>
/// <param name="account"></param>
/// <returns></returns>
public static bool Exists(string account)
{
return (Data.Manager.GetObjectCount<Connection>("Account = ?", account) != 0);
}
/// <summary>
/// Returns the current connection information for the specified account.
/// </summary>
/// <param name="account"></param>
/// <returns><b>null</b> if specified account has no controller currently connected.</returns>
public static Collection<Connection> Find(string account)
{
return Data.Manager.GetCollection<Connection>(new OPathQuery<Connection>("Account == ?"), account);
}
public static Connection Find(string account, string controllerUuid)
{
return Data.Manager.GetObject<Connection>(new OPathQuery<Connection>("Account == ? && ControllerUuid == ?"), account, controllerUuid);
}
/// <summary>
/// Returns all connections in the connection list.
/// </summary>
public static Collection<Connection> GetAll()
{
return Data.Manager.GetCollection<Connection>("");
}
/// <summary>
/// Removes an account connection from the remote access connections list.
/// </summary>
/// <param name="account"></param>
public static void Remove(Connection connection)
{
Data.Manager.MarkForDeletion(connection);
Data.Manager.PersistChanges(connection);
}
public static void Save(Connection connection)
{
Data.Manager.PersistChanges(connection, PersistDepth.SingleObject);
}
}
}
}
Mappings.config
<? xml version="1.0" encoding="utf-8" ?>
< mappings version="4.0" >
< entity type="Control4.Web.RemoteAccess.Server" table="Server" keyMember="_Id" keyType="Auto">
< attribute member="_Id" field="Id" alias="Id" />
< attribute member="_Address" field="Address" alias="Address" />
< attribute member="_ServiceUrl" field="ServiceUrl" alias="ServiceUrl" />
< relation relationship="OneToMany" member="_Connections" field="ServerId" type="Control4.Web.RemoteAccess.Server.Connection" lazyLoad="true" cascadeDelete="true" />
</ entity>
< entity type="Control4.Web.RemoteAccess.Server.Connection" table="Connection" keyMember="_Id" keyType="Auto">
< attribute member="_Id" field="Id" alias="Id" />
< attribute member="_Account" field="Account" alias="Account" />
< attribute member="_ControllerUuid" field="ControllerUuid" alias="ControllerUuid" />
< attribute member="_ControllerAddress" field="ControllerAddress" alias="ControllerAddress" />
< attribute member="_ServerId" field="ServerId" alias="ServerId" />
< relation relationship="ManyToOne" member="_Server" field="ServerId" type="Control4.Web.RemoteAccess.Server" lazyLoad="true" />
</ entity>
</ mappings>
Thanks,
Cris |
| 4/10/2006 2:23:36 PM |
Eureka -- it is supported, and always has been -- you just have to know how .NET expects you to format the type ! It turns out that you have to use a "+" instead of a "." to delimit the nested class when using reflection -- so something like: "Name.Space.Main+Nested". Its even in the docs, although it proved very hard to find: see this.
Thanks, Paul Wilson
|