I have several objects in my solution that use the following pattern:
#region Repositories
private RepositoryAccount _account;
private RepositoryInquiry _inquiry;
private RepositoryLoan _loan;
public RepositoryAccount Account { get { return _account ?? (_account = new RepositoryAccount(this)); } }
public RepositoryInquiry Inquiry { get { return _inquiry ?? (_inquiry = new RepositoryInquiry(this)); } }
public RepositoryLoan Loan { get { return _loan ?? (_loan = new RepositoryLoan(this)); } }
#endregion
I created a Generic Class to try to make the Property handling a little cleaner but ran into a snag. The Property Class looks like:
public class Property<T> where T : class, new()
{
private T _value;
public T Value
{
get { return _value ?? (_value = new T()); }
set
{
// insert desired logic here
_value = value;
}
}
public static implicit operator T(Property<T> value)
{
return value.Value;
}
public static implicit operator Property<T>(T value)
{
return new Property<T> { Value = value };
}
}
I replace my property (with backing objects) with the new Generic Property like:
public Property<RepositoryAccount> Account { get; set; }
public Property<RepositoryInquiry> Inquiry { get; set; }
public Property<RepositoryLoan> Loan { get; set; }
However, if you noticed in the original public getter, I need to instantiate each object with another object: this is required and there is no paramaterless constructor for these repository objects.
Any suggestions?
The whole object looks like:
public class UnitOfWorkSymitar : IUnitOfWork
{
#region Properties
internal IPHostEntry IpHostInfo;
internal IPAddress IpAddress;
internal IPEndPoint RemotEndPoint;
internal System.Net.Sockets.Socket Sender;
internal byte[] Bytes = new byte[1024];
internal bool IsAllowedToRun = false;
internal string SymServerIp;
internal int SymPort;
public string State { get; set; }
#endregion
#region Constructor
public UnitOfWorkSymitar() { OpenSymitarConnection(); }
protected UnitOfWorkSymitar(string serverIp, int? port) { OpenSymitarConnection(serverIp, port); }
#endregion
#region Implement IUnitOfWork
public void Commit() { /* No commit on this socket connection */ }
public void Rollback() { /* No rollback on this socket connection */ }
#endregion
#region Implement IDisposable
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
public void Dispose()
{
CloseSymitarConnection();
}
#endregion
#region Private Helpers
/// <summary>
/// Connect to a remote device.
/// </summary>
/// <returns>Success/failure message</returns>
private string OpenSymitarConnection(string serverIp = null, int? port = null)
{
var config = ConfigInfoSymitar.Instance;
SymServerIp = serverIp ?? config.SymServerIp;
SymPort = port ?? config.SymPort;
try
{
// Establish the remote endpoint for the socket.
//IpHostInfo = Dns.GetHostEntry(SymServerIp);
//IpAddress = IpHostInfo.AddressList[0];
IpAddress = Dns.GetHostAddresses(SymServerIp)[0];
RemotEndPoint = new IPEndPoint(IpAddress, SymPort);
// Create a TCP/IP socket.
Sender = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Connect the socket to the remote endpoint. Catch any errors.
Sender.Connect(RemotEndPoint);
}
catch (Exception ex)
{
State = DetermineError(ex);
return State;
//throw;
}
IsAllowedToRun = true;
State = "Success";
return State;
}
/// <summary>
/// Setup and send the request
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public string SendMessage(string request)
{
try
{
// Encode the data string into a byte array and add the carriage return for SymConnect.
var msg = Encoding.ASCII.GetBytes(request);
if(!request.EndsWith("\n"))
msg = Encoding.ASCII.GetBytes(request + "\n");
// Send the data through the socket.
var bytesSent = Sender.Send(msg);
// Receive the response from the remote device.
var bytesRec = Sender.Receive(Bytes);
var response = Encoding.ASCII.GetString(Bytes, 0, bytesRec);
response = response.Replace("\n", "");
return response;
}
catch (Exception ex)
{
return DetermineError(ex);
}
}
/// <summary>
/// Close the connection to a remote device.
/// </summary>
/// <returns></returns>
private string CloseSymitarConnection()
{
try
{
// Release the socket.
Sender.Shutdown(SocketShutdown.Both);
Sender.Close();
}
catch (Exception ex)
{
return DetermineError(ex);
}
finally
{
IsAllowedToRun = false;
}
return "Success!";
}
/// <summary>
/// Determine if this is an Arguments, Socket or some other exception
/// </summary>
/// <param name="ex">The exception to be checked</param>
/// <returns>String message</returns>
private static string DetermineError(Exception ex)
{
if (ex.GetType() == typeof(ArgumentNullException))
return "Missing Arguments: " + Environment.NewLine + ex.GetFullMessage();
if (ex.GetType() == typeof(SocketException))
return "Socket Error: " + Environment.NewLine + ex.GetFullMessage();
return "Unexpected Error: " + Environment.NewLine + ex.GetFullMessage();
}
#endregion
#region Symitar Samples
private static string ExecSymConnectRequest(string symServerIP, int symPort, string request)
{
// Data buffer for incoming data.
var bytes = new byte[1024];
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
var ipHostInfo = Dns.GetHostEntry(symServerIP);
var ipAddress = ipHostInfo.AddressList[0];
var remoteEP = new IPEndPoint(ipAddress, symPort);
// Create a TCP/IP socket.
var sender = new System.Net.Sockets.Socket(AddressFamily.InterNetwork
, SocketType.Stream
, ProtocolType.Tcp);
// Connect the socket to the remote endpoint. Catch any errors.
try
{
sender.Connect(remoteEP);
// Encode the data string into a byte array and add the carriage return for SymConnect.
var msg = Encoding.ASCII.GetBytes(request + "\n");
// Send the data through the socket.
var bytesSent = sender.Send(msg);
// Receive the response from the remote device.
var bytesRec = sender.Receive(bytes);
var response = Encoding.ASCII.GetString(bytes, 0, bytesRec);
// Release the socket.
sender.Shutdown(SocketShutdown.Both);
sender.Close();
response.Replace("\n", "");
return response;
}
catch (ArgumentNullException ane)
{
return "Missing Arguments: " + ane.Message;
}
catch (SocketException se)
{
return "Socket Error: " + se.Message;
}
catch (Exception e)
{
return "Unexpected Error: " + e.Message;
}
}
catch (Exception e)
{
return e.Message;
}
}
#endregion
#region Repositories
private RepositoryAccount _account;
private RepositoryInquiry _inquiry;
private RepositoryLoan _loan;
public RepositoryAccount Account { get { return _account ?? (_account = new RepositoryAccount(this)); } }
public RepositoryInquiry Inquiry { get { return _inquiry ?? (_inquiry = new RepositoryInquiry(this)); } }
public RepositoryLoan Loan { get { return _loan ?? (_loan = new RepositoryLoan(this)); } }
#endregion
}