C# InteropServices and Visual Basic 6.0 error reference error - c#

I created C# dll to use with Visual Basic 6. When I create a reference in VB6 I get the error:
Error 91: Object variable or With block variable not set
I tried to set the object of different ways but i still having the same problem.
VISUAL BASIC 6.0 Code:
Private Sub Command1_Click()
Dim objhacienda As SolcomFE.clsHacienda
Set objhacienda = New SOLCOMFE.clsHacienda' Error can not create the object 429
Dim blnResult As Boolean
blnResult = objhacienda.tengoAcceso Error 91: Object variable or With block variable not set
end sub
C# Code:
namespace SolcomFE
{
[
ComVisible(true), //Hace visible las interfaces
GuidAttribute("4F52E06E-29C6-4168-8AC2-F836CD7A1C4A"), //Tomado del asembly del proyecto
Description("Interfaces para acceso de factura electronica")
// ClassInterface(ClassInterfaceType.None)
]
//----------------------------------------------------DiseƱo de interfaces -------------------------------------//
public interface IclsHacienda
{
[DispId(1)]
bool tengoAcceso();
[DispId(2)]
void configuracion(bool pBlnEnvioProduccion,
string pStrUsuarioHacienda,
string pStrClaveHacienda,
string pStrPinCerti,
string pStrRutaCerti,
string pStrRutaArchEnvio = "C://HACIENDA/Almacenamiento/",
string pStrRutaArchRespuesta = "C://HACIENDA/Almacenamiento/");
[DispId(3)]
string[] registrarDocElectronico(
string pStrVerificador,
byte pBytSituacionEnCom,
DocumentoEncabezado pLstEncabezadoDoc
);
}
//-------------------------------------------Clases ---------------------------------------------------------//
[ClassInterface(ClassInterfaceType.None)]
[Guid("64B7C116-BA68-4EE0-8340-74F64846CB3D")]
public class clsHacienda : IclsHacienda
{
//------------------------------------------ Atributos de la clase --------------------------------------//
private bool EnvioProduccion //
{
get
{
return envioProduccion;
}
set
{
envioProduccion = value;
}
}
private string UsuarioHacienda //
{
get
{
return usuariohacienda;
}
set
{
usuariohacienda = value;
}
}
private string ClaveHacienda //
{
get
{
return clavehacienda;
}
set
{
clavehacienda = value;
}
}
private string RutaCertificado
{
get
{
return rutacertificado;
}
set
{
rutacertificado = value;
}
}
private string RutaArchEnvio
{
get
{
return rutaarchenvio;
}
set
{
rutaarchenvio = value;
}
}
private string RutArchrespuesta
{
get
{
return rutaarchrespuesta;
}
set
{
rutaarchrespuesta = value;
}
}
private string PinCertificado
{
get
{
return pincertificado;
}
set
{
pincertificado = value;
}
}
public clsHacienda() { }
public bool tengoAcceso() { return true; }
public void configuracion(bool pBlnEnvioProduccion,
string pStrUsuarioHacienda,
string pStrClaveHacienda,
string pStrPinCerti,
string pStrRutaCerti,
string pStrRutaArchEnvio = "C://HACIENDA/Almacenamiento/",
string pStrRutaArchRespuesta = "C://HACIENDA/Almacenamiento/")
{
EnvioProduccion = pBlnEnvioProduccion;
UsuarioHacienda = pStrUsuarioHacienda;
ClaveHacienda = pStrClaveHacienda;
PinCertificado = pStrPinCerti;
RutaCertificado = pStrRutaCerti;
RutaArchEnvio = pStrRutaArchEnvio;
RutArchrespuesta = pStrRutaArchRespuesta;
}
public string[] registrarDocElectronico(
string pStrVerificador,
byte pBytSituacionEnCom,
DocumentoEncabezado pLstEncabezadoDoc
)
{
string[] strArrValores = new string[10];
return strArrValores;
}
}
}

It's difficult to find out whats wrong. Specially because i don't have VB6 ;-). Anyway, I've found some differences on your implementation. Check if this rings a bell:
Interfaces:
[ComVisible(true)]
[Guid("E449B0E6-2F27-46B7-9CC0-C7032B7B5BF1")]
public interface IclsHacienda
{
[DispId(1)]
bool tengoAcceso();
[DispId(2)]
void configuracion(bool pBlnEnvioProduccion,
string pStrUsuarioHacienda,
string pStrClaveHacienda,
string pStrPinCerti,
string pStrRutaCerti,
string pStrRutaArchEnvio,
string pStrRutaArchRespuesta);
[DispId(3)]
string[] registrarDocElectronico(
string pStrVerificador,
byte pBytSituacionEnCom,
IDocumentoEncabezado pLstEncabezadoDoc
);
}
[ComVisible(true)]
[Guid("97F8901F-EEDA-4DE1-8B4B-826ED43E17D8")]
public interface IDocumentoEncabezado
{
int MyProperty { get; set; }
}
Implementation:
[ComVisible(true)]
[Guid("4726F93F-D102-442E-AF7D-3255B87E740C")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IDocumentoEncabezado))]
public class DocumentoEncabezado : IDocumentoEncabezado
{
public int MyProperty { get; set; }
}
[ComVisible(true)]
[Guid("500941FB-3F7B-4285-BF4A-A642D60AD923")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IclsHacienda))]
public class ClsHacienda : IclsHacienda
{
public void configuracion(bool pBlnEnvioProduccion, string pStrUsuarioHacienda, string pStrClaveHacienda, string pStrPinCerti, string pStrRutaCerti, string pStrRutaArchEnvio , string pStrRutaArchRespuesta)
{
Debug.WriteLine("Called configuracion");
}
public string[] registrarDocElectronico(string pStrVerificador, byte pBytSituacionEnCom, IDocumentoEncabezado pLstEncabezadoDoc)
{
Debug.WriteLine("Called registrarDocElectronico");
return new string[] { "Whatever" };
}
public bool tengoAcceso()
{
Debug.WriteLine("Called tengoAcceso");
return false;
}
}
If not, there is something wrong on the VB side...

Thank your for your help.
I found a solution
create 2 clases, one inteface class, another method class
Example iInterface, COMInterface,
COMIterface implements iInterface.
Go to tools and create GUID
Then create a key. Implement_OleCreate and paste it to iInterface class,
After create a new key a 5.Guid Class
More documentation
https://social.technet.microsoft.com/wiki/contents/articles/37338.com-interop-detail-steps-to-create-com-interop-dll.aspx

Related

How to best design a class that might contain null object

I'm about to design a class that more often then not will contain a reference to a Null value. It reminded me of nullable Datetime which has a boolean value to indicate if there is an actual value stored.
DateTime? dt = new DateTime?();
if(dt.HasValue)
{
//DoStuff
}
Is it a good coding practice to design a class as follows?
class Computer
{
public string Name;
public string ID;
//...
public bool IsHiveMind;
public HiveMindInfo RegInfo;
}
class HiveMindInfo
{
string SecretLocation;
int BaudRate;
int Port;
}
...and to use it...
Computer aComputer = GetComputer(...);
if(aComputer.IsHiveMind)
{
Network.DoHostileTakeOver(aComputer); //!
}
How about this code below?
It seems you can remove IsHiveMind variable since HiveMindInfo variable has the same meaning by checking its null or not.
class Computer
{
public string Name;
public string ID;
public HiveMindInfo RegInfo;
}
class HiveMindInfo
{
string SecretLocation;
int BaudRate;
int Port;
}
Computer aComputer = GetComputer(...);
if (aComputer != null && aComputer.RegInfo != null)
{
Network.DoHostileTakeOver(aComputer);
}
To answer your question, you could implement the code as proposed.
An alternative would be to consider the following design patterns:
Proxy Design Pattern
Strategy Design Pattern
Sample Code
interface ITakeOverStrategy
{
void Execute();
}
class KevinFlynnHackerStrategy : ITakeOverStrategy
{
public void Execute()
{
// a nod to Tron
}
}
class NeoHackerStrategy: ITakeOverStrategy
{
private readonly HiveMindInfo _hiveMindInfo;
public NeoHackerStrategy(HiveMindInfo info)
{
_hiveMindInfo = info;
}
public void Execute()
{
// Mr. Anderson!
}
}
// This is a surrogate class.
// ... The value returned by String.Empty is often used as a surrogate.
class IdleStrategy : ITakeOverStrategy
{
public void Execute()
{
// do nothing
}
}
class Computer
{
private readonly ITakeOverStrategy _takeoverStrategy ;
public Computer(ITakeOverStrategy strategy)
{
_takeoverStrategy = strategy;
}
public Subjugate()
{
// insert epic code here
_takeoverStrategy.Execute();
}
}
Then somewhere in your code you create an instance of Computer with the appropriate strategy:
var info = new HiveMindInfo();
// update instance parameters
var computer = new Computer(new NeoHackerStrategy(info));
computer.Subjugate();
UPDATES
August 13th, 2015 # 10:13 EST
My comment about structs is not within the scope of the original question, and has been removed:
If your classes are only going to contain fields/properties then I would consider converting them into struct.
Just add ? to your object:
class Computer
{
public string Name;
public string ID;
//...
public HiveMindInfo? RegInfo;
}
struct HiveMindInfo
{
string SecretLocation;
int BaudRate;
int Port;
}
And then check it exactly as you did with datetime:
Computer aComputer = GetComputer(...);
if (aComputer.RegInfo.HasValue)
{
// Do something
}

C# design guideline - calling appropriate method based on string value

Looking for design guidelines for the following problem.
I'm receiving two string values - action and message and have to call appropriate method which processes string message (processM1MessageVer1, processM1MessageVer2, processM2MessageVer1...). The method I have to call depends on the given string action. There are 2 versions (but in future there might be more) of each processing method. The version of method I have to call is determined by global variable version. Every method returns object of different type (ResultObject1, ResultObject2...). The result has to be serialized, converted to base64 and returned back.
Is there more elegant way of writing this (eliminate duplicate code, make possible future changes easier, reduce code...):
string usingVersion = "ver1";
public string processRequest(string action, string message)
if (usingVersion == "ver1"){
processRequestVer1(action, message);
}
else{
processRequestVer2(action, message);
}
}
//version 1
public string processRequestVer1(string action, string message){
string result = "";
switch (action){
case "m1":
ResultObject1 ro = processM1MessageVer1(message);
result = serialize(ro);
result = convertToB64(result);
case "m2":
ResultObject2 ro = processM2MessageVer1(message);
result = serialize(ro);
result = convertToB64(result);
case "m3":
ResultObject3 ro = processM3MessageVer1(message);
result = serialize(ro);
result = convertToB64(result);
}
return result;
}
//version 2
public string processRequestVer2(string action, string message){
string result = "";
switch (action){
case "m1":
ResultObject1 ro = processM1MessageVer2(message);
result = serialize(ro);
result = convertToB64(result);
case "m2":
ResultObject2 ro = processM2MessageVer2(message);
result = serialize(ro);
result = convertToB64(result);
case "m3":
ResultObject3 ro = processM3MessageVer2(message);
result = serialize(ro);
result = convertToB64(result);
}
return result;
}
It would be simplier if messages that have to be processed are of different object types instead of strings so that appropriate method could be called polymorphically. The fact that every process method returns different object type also complicates things even more. But these don't depend on me and I cannot change it.
My approach (make it more object oriented, and you should justify whether it's appropriate to create class structure depending on how complex your processing logic is. If your processing logic is only little then maybe this is over-engineering):
For serialize and convert to base 64, I assume you have some logic to do those tasks in a generic way. If not, move those to sub class also
public interface IRequestProcessorFactory
{
IRequestProcessor GetProcessor(string action);
}
public class FactoryVersion1 : IRequestProcessorFactory
{
public IRequestProcessor GetProcessor(string action)
{
switch(action)
{
case "m1":
return new M1Ver1RequestProcessor();
case "m2":
return new M2Ver1RequestProcessor();
case "m3":
return new M3Ver1RequestProcessor();
default:
throw new NotSupportedException();
}
}
}
public class FactoryVersion2 : IRequestProcessorFactory
{
public IRequestProcessor GetProcessor(string action)
{
switch(action)
{
case "m1":
return new M1Ver2RequestProcessor();
case "m2":
return new M2Ver2RequestProcessor();
case "m3":
return new M3Ver2RequestProcessor();
default:
throw new NotSupportedException();
}
}
}
public interface IRequestProcessor
{
string ProcessRequest(string message);
}
public class RequestProcessorBase<T>
{
public string ProcessRequest(string message)
{
T result = Process(message);
string serializedResult = Serialize(result);
return ConvertToB64(serializedResult);
}
protected abstract T Process(string message);
private string Serialize(T result)
{
//Serialize
}
private string ConvertToB64(string serializedResult)
{
//Convert
}
}
public class M1Ver1RequestProcessor : RequestProcessorBase<ResultObject1>
{
protected ResultObject1 Process(string message)
{
//processing
}
}
public class M2Ver1RequestProcessor : RequestProcessorBase<ResultObject2>
{
protected ResultObject2 Process(string message)
{
//processing
}
}
public class M3Ver1RequestProcessor : RequestProcessorBase<ResultObject3>
{
protected ResultObject3 Process(string message)
{
//processing
}
}
public class M1Ver2RequestProcessor : RequestProcessorBase<ResultObject1>
{
protected ResultObject1 Process(string message)
{
//processing
}
}
public class M2Ver2RequestProcessor : RequestProcessorBase<ResultObject2>
{
protected ResultObject2 Process(string message)
{
//processing
}
}
public class M3Ver2RequestProcessor : RequestProcessorBase<ResultObject3>
{
protected ResultObject3 Process(string message)
{
//processing
}
}
Usage:
string action = "...";
string message = "...";
IRequestProcessorFactory factory = new FactoryVersion1();
IRequestProcessor processor = factory.GetProcessor(action);
string result = processor.ProcessRequest(message);
The switch is still there in factory class, but it only returns processor and doesn't do actual work so it's fine for me
First - define interface that suit you best, like this
public interface IProcessMessage
{
string ActionVersion { get; }
string AlgorithmVersion { get; }
string ProcessMessage(string message);
}
Then create as many implementation as you need
public class processorM1Ver1 : IProcessMessage
{
public string ProcessMessage(string message)
{
ResultObject1 ro1 = processM1MessageVer1(message);
var result = serialize(ro1);
result = convertToB64(result);
return result;
}
public string ActionVersion {get { return "m1"; }}
public string AlgorithmVersion {get { return "ver1"; }}
}
public class processorM2Ver1 : IProcessMessage
{
public string ActionVersion {get { return "m2"; }}
public string AlgorithmVersion {get { return "ver1"; }}
public string ProcessMessage(string message)
{
ResultObject1 ro1 = processM2MessageVer1(message);
var result = serialize(ro1);
result = convertToB64(result);
return result;
}
}
public class processorM1Ver2 : IProcessMessage
{
public string ActionVersion {get { return "m1"; }}
public string AlgorithmVersion {get { return "ver2"; }}
public string ProcessMessage(string message)
{
ResultObject1 ro1 = processM1MessageVer2(message);
var result = serialize(ro1);
result = convertToB64(result);
return result;
}
}
Now you need something that know which implementation is best in current context
public class MessageProcessorFactory
{
private MessageProcessorFactory() { }
private static readonly MessageProcessorFactory _instance = new MessageProcessorFactory();
public static MessageProcessorFactory Instance { get { return _instance; }}
private IEnumerable<IProcessMessage> _processorCollection;
IEnumerable<IProcessMessage> ProcessorCollection
{
get
{
if (_processorCollection == null)
{
//use reflection to find all imlementation of IProcessMessage
//or initialize it manualy
_processorCollection = new List<IProcessMessage>()
{
new processorM1Ver1(),
new processorM2Ver1(),
new processorM1Ver2()
};
}
return _processorCollection;
}
}
internal IProcessMessage GetProcessor(string action)
{
var algorithVersion = ReadAlgorithVersion();
var processor = ProcessorCollection.FirstOrDefault(x => x.AlgorithmVersion == algorithVersion && x.ActionVersion == action);
return processor;
}
private string ReadAlgorithVersion()
{
//read from config file
//or from database
//or where this info it is kept
return "ver1";
}
}
It can be use in such way
public class Client
{
public string ProcessRequest(string action, string message)
{
IProcessMessage processor = MessageProcessorFactory.Instance.GetProcessor(action);
return processor.ProcessMessage(message);
}
}

fill generic list<> of a class file with data by specific variables

The question is rather about serialized generic list<>
I have used a tool xsd2code for generating a serialized class file from xml schema to generate xml file on given data.
The class file contains all the xml data fields variables into classes as bellow-
public partial class Awmds
{
private List bol_segmentField;
public Awmds()
{
this.bol_segmentField = new List<AwmdsBol_segment>();
}
public List<AwmdsBol_segment> Bol_segment
{
get
{
return this.bol_segmentField;
}
set
{
this.bol_segmentField = value;
}
}
}
public partial class AwmdsBol_segment
{
private AwmdsBol_segmentBol_id bol_idField;
private sbyte consolidated_CargoField;
private AwmdsBol_segmentLoad_unload_place load_unload_placeField;
private AwmdsBol_segmentTraders_segment traders_segmentField;
private List<AwmdsBol_segmentCtn_segment> ctn_segmentField;
private AwmdsBol_segmentGoods_segment goods_segmentField;
private string value_segmentField;
public AwmdsBol_segment()
{
this.goods_segmentField = new AwmdsBol_segmentGoods_segment();
this.ctn_segmentField = new List<AwmdsBol_segmentCtn_segment>();
this.traders_segmentField = new AwmdsBol_segmentTraders_segment();
this.load_unload_placeField = new AwmdsBol_segmentLoad_unload_place();
this.bol_idField = new AwmdsBol_segmentBol_id();
}
public AwmdsBol_segmentBol_id Bol_id
{
get
{
return this.bol_idField;
}
set
{
this.bol_idField = value;
}
}
public sbyte Consolidated_Cargo
{
get
{
return this.consolidated_CargoField;
}
set
{
this.consolidated_CargoField = value;
}
}
.... and so on for other fields ....
}
public partial class AwmdsBol_segmentBol_id
{
private string bol_referenceField;
private sbyte line_numberField;
private sbyte bol_natureField;
private string bol_type_codeField;
public string Bol_reference
{
get
{
return this.bol_referenceField;
}
set
{
this.bol_referenceField = value;
}
}
public sbyte Line_number
{
get
{
return this.line_numberField;
}
set
{
this.line_numberField = value;
}
}
public sbyte Bol_nature
{
get
{
return this.bol_natureField;
}
set
{
this.bol_natureField = value;
}
}
public string Bol_type_code
{
get
{
return this.bol_type_codeField;
}
set
{
this.bol_type_codeField = value;
}
}
}
.... and so on for other classes ....
I have all the data to fill the generic list: List bol_segmentField
My problem is I dont know how to insert the data to the members of List bol_segmentField based on the class file.
Someone please help me to fillup the generic list by the class variables.
Maybe I am missing something, but would this work:
var awds = new Awmds();
var segment = new AwmdsBol_segment();
// here fill in the segment
awds.Bol_segment.Add(segment);

Return modified generic type

I am trying to modify an object after its creation. I would like to set the properties of this object to -1 for int or string.empty "" for a string. Bellow is a sample code of what I already have.
class TestClassAccess{
public int MyPropInt { get; set { ModifyOnAccessDenied<int>(value); } }
public string MyPropString { get; set { ModifyOnAccessDenied<string>(value); } }
public TestClassAccess() { }
private T ModifyOnAccessDenied<T>(T propertyToChange) {
var _hasAccess = false; //not really important how this is made
if (!_hasAccess)
{
if (propertyToChange is string)
propertyToChange = string.Empty;
else if (propertyToChange is int)
propertyToChange = -1;
}
return propertyToChange;
}
}
so.. issues i am having.
It doesn't compile as I cannot convert property to change to string or int.
I don't knot if i can use set methods like this.
Is this possible or am i being to ambitious.
Thank.s
KJ
If you are checking for specific types in a generic function you are probably doing something wrong. In this case you can easily just pass in a default value rather than having it hard coded:
private T ModifyOnAccessDenied<T>(T newValue, T defaultValue) {
var _hasAccess = false; //not really important how this is made
if (!_hasAccess)
{
newValue = defaultValue;
}
return newValue;
}
I've also renamed propertyToChange to newValue because what you have in this function is the new value, not a property.
Also your property definitions will not work. If you need to include any logic in your getter or setting you cannot use the auto-initializer syntax and must implement the property with a backing field.
There doesn't seem to be a point in making this function generic if it needs specific action for each type. This seems more appropriate.
class TestClassAccess
{
public int MyPropInt { get; set { ModifyOnAccessDenied<int>(value); } }
public string MyPropString { get; set { ModifyOnAccessDenied<string>(value); } }
public TestClassAccess() { }
private static volatile bool _hasAccess = false;
private string ModifyOnAccessDenied<string>(string propertyToChange)
{
if (!_hasAccess)
return string.Empty;
return propertyToChange;
}
private int ModifyOnAccessDenied<int>(int propertyToChange)
{
if (!_hasAccess)
return -1;
return propertyToChange;
}
}
You can however do this using dynamics, but this does require .NET 4.0
private T ModifyOnAccessDenied<T>(T propertyToChange)
{
if (!_hasAccess)
{
if (propertyToChange is string)
return (dynamic)string.Empty;
else if (propertyToChange is int)
return (dynamic)(int)-1;
}
return propertyToChange;
}
Fully working sample:
static class Program
{
[STAThread]
static void Main()
{
TestClassAccess test = new TestClassAccess();
test.MyPropInt = 4;
test.MyPropString = "TEST";
Console.WriteLine("MyPropInt {0}, MyPropString '{1}'",test.MyPropInt, test.MyPropString);
// Prints "MyPropInt -1, MyPropString ''
}
class TestClassAccess
{
private int myPropInt = 0;
public int MyPropInt { get { return myPropInt; } set { myPropInt = ModifyOnAccessDenied<int>(value); } }
private string myPropString = string.Empty;
public string MyPropString { get { return myPropString; } set { myPropString = ModifyOnAccessDenied<string>(value); } }
public static volatile bool _hasAccess = false;
private T ModifyOnAccessDenied<T>(T propertyToChange)
{
if (!_hasAccess)
{
if (propertyToChange is string)
return (dynamic)string.Empty;
else if (propertyToChange is int)
return (dynamic)(int)-1;
}
return propertyToChange;
}
}
}

Upcasting without any added data fields

In my project I have a generic Packet class. I would like to be able to upcast to other classes (like LoginPacket or MovePacket).
The base class contains a command and arguments (greatly simplified):
public class Packet
{
public String Command;
public String[] Arguments;
}
I would like to have be able to convert from Packet to LoginPacket (or any other) based on a check if Packet.Command == "LOGIN". The login packet would not contain any new data members, but only methods for accessing specific arguments. For example:
public class LoginPacket : Packet
{
public String Username
{
get { return Arguments[0]; }
set { Arguments[0] == value; }
}
public String Password
{
get { return Arguments[1]; }
set { Arguments[1] == value; }
}
}
It would be great if I could run a simple code that would cast from Packet to LoginPacket with something like LoginPacket _Login = (LoginPacket)_Packet;, but that throws a System.InvalidCastException.
It seems like this would be an easy task, as no new data is included, but I can't figure out any other way than copying everything from the Packet class to a new LoginPacket class.
A better approach is to make Packet instance encapsulated by LoginPacket.
This will allow you to do:
LoginPacket _Login = new LoginPacket(_packet);
Also consider creating a PacketFactory where all the logic needed to create various Packet's goes in.
public class Packet
{
public String Command;
public String[] Arguments;
}
public abstract class AbstractPacket
{
private Packet _packet;
public AbstractPacket(Packet packet)
{
_packet = packet;
}
public string this[int index]
{
get { return _packet.Arguments[index]; }
set { _packet.Arguments[index] = value; }
}
}
public class LoginPacket : AbstractPacket
{
public LoginPacket(Packet packet): base(packet)
{
}
public string Username
{
get { return base[0]; }
set { base[0] = value; }
}
public string Password
{
get { return base[1]; }
set { base[1] = value; }
}
}
If different type of Packets differ only by available data members then you could do something below:
Use PacketGenerator to generate packets as:
Packet packet = PacketGenerator.GetInstance(packetdata);
Access the properties as:
Console.WriteLine("User Name: {0}", packet["UserName"]);
Code..
public enum PacketType { Undefined, LoginPacket, MovePacket }
public class PacketData
{
public String Command;
public String[] Arguments;
}
public class Packet
{
public readonly PacketType TypeOfPacket;
private Dictionary<string, string> _argumentMap;
public Packet(PacketType _packetType,
Dictionary<string, string> argumentMap)
{
TypeOfPacket = _packetType;
_argumentMap = argumentMap;
}
public string this[string index]
{
get { return _argumentMap[index]; }
set { _argumentMap[index] = value; }
}
}
public static class PacketFactory
{
Packet GetInstance(PacketData packetData)
{
Dictionary<string, string> argumentMap
= new Dictionary<string, string>();
PacketType typeOfPacket = PacketType.Undefined;
// Replace inline strings/int with static/int string definitions
switch (packetData.Command.ToUpper())
{
case "LOGIN":
typeOfPacket = PacketType.LoginPacket;
argumentMap["UserName"] = packetData.Arguments[0];
argumentMap["PassWord"] = packetData.Arguments[1];
break;
case "MOVE":
typeOfPacket = PacketType.MovePacket;
//..
break;
default:
throw new ArgumentException("Not a valid packet type");
}
return new Packet(typeOfPacket, argumentMap);
}
}

Categories

Resources