|
I'm having trouble with the interface for the Factory Design Pattern. I've looked at
http://dotnet.dzone.com/articles/design-patterns-c-factory,
which follows my design very closely since it was the first good example I found a while back.
I took a look at
http://stackoverflow.com/questions/27294/abstract-factory-design-pattern,
but my design is very different.
Right now, this is what it looks like. I have included a lot of code because I have a feeling the problem has to do with the visual studio project breakdown. It used to be more simple, with my CR5, interface, factory, CB_spec, El, etc in the same visual studio project. I had to move things around as shown per design discussions and the need for CR6, etc to be separate. Now I'm getting some compilation problems I'm not sure what to do with. See ** below for the first and worst. My question is regarding the compilation issue below.
My iCR Visual Studio project which is the interface:
public interface iCR
{
int CB_IO_Init(int slaveIndex);
int WritePortReady();
int WritePortBusy();
void initCRData(byte[] writeBuffer, byte[] statusBuffer, int SlaveIndex, USB_Comm.CB cb, int cr_Type);
int ProcessTWriting(ref Byte[] writeDat, ref Byte[] statusDat, ref Byte[] dataDumpWriteCheck);
void Failure(String message);
void Success(String message);
}
My CR_Factory Visual Studio project
namespace CR_Factory
{
public class Cr
{
}
public class CRFactory
{
public enum CRType
{
CR0,
CR1,
CR3,
CR4,
CR5,
CR6
}
public CRFactory()
{
}
public iCR GetCR(CRType type)
{
iCR cr = null;
switch (type)
{
case CRType.CR5:
cr = new CR5();
break;
case CRType.CR6:
break;
default:
throw new ArgumentException(string.Format("A CR of type {0} cannot be found", Enum.GetName(typeof(CRType), type)));
}
return cr;
}
public CRType DetermineCR_Type(int type)
{
switch (type)
{
case 0:
return CRType.CR0;
case 1:
return CRType.CR1;
case 3:
return CRType.CR3;
case 4:
return CRType.CR4;
case 5:
return CRType.CR5;
case 6:
return CRType.CR6;
default:
throw new ArgumentException(string.Format("A type of type {0} cannot be found", type));
}
}
}
}
My CR5 Visual Studio Project has a lot of classes in it, but right now I’m just showing you the part referred to in the factory. Later I’ll create a CR6 VS project, etc. As you can see, the compiler doesn't think I implemented initCRData but it's right there, and curly brackets are fine.
public class CR5 : iCR **compile error CR5_new.CR5 does not implement interface member iCR.initCRData(byte[],byte[],int,USB_Comm.CB,int)
{
CB_703 cb_specific = null;
public CR5()
{
cb_specific = new CB_703(SlaveIndex);
}
public void initCRData(byte[] writeBuffer, byte[] statusBuffer, int slaveIndex, USB_Comm.CB cb_specificInstance, int crType)
{...
}
public int CB_IO_Init(int SlaveIndex)
{
int result = -534;
result = cb_specific.IO_Init(SlaveIndex);
return result;
}
.
.
.
}
I have another Visual Studio Project (actually several) that instantiates the factory and gets the appropriate type. We’ll call it El:
namespace CrWr
{
public partial class PControl : UserControl
{
public PControl()
{
}
public Control GetPControl(USB_Comm.CB cbInstance, string dllSelected, THandlerApplication.Temp.TEMP[] temp, string dll, SC.SC.S_C c0)
{
cb = cbInstance;
createControls();
itsDll = dll;
tArr = temp;
cert = c0;
CR_Factory.CRFactory factory = new CR_Factory.CRFactory();
CRFactory.CRType type = factory.DetermineCR_Type(cr_Type);
try
{
cr = factory.GetCR(type); }
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
}
return this;
}
private void OnP()
{
int result = -536;
while (rL)
{
result = cr.CB_IO_Init(SlaveIndex);
if (result == 0)
{
…
}
}
.
.
.
}
|
|
|
|
|
Try this;
public class CR5 : iCR
{
CB_703 cb_specific = null;
public CR5()
{
cb_specific = new CB_703(SlaveIndex);
}
public void iCR.initCRData(byte[] writeBuffer, byte[] statusBuffer, int slaveIndex, USB_Comm.CB cb_specificInstance, int crType)
{...
}
public int CB_IO_Init(int SlaveIndex)
{
int result = -534;
result = cb_specific.IO_Init(SlaveIndex);
return result;
}
|
|
|
|
|
When I do that, the compilation error turns to:
The modifier 'public' is not valid for this item.
|
|
|
|
|
Makes sense. Being an interface, marking it public would be redundant. Delete the keyword.
|
|
|
|
|
Thanks for the comment. I got rid of "public" so now it's
void iCR.initCRData(byte[] wrBuff, byte[] stBuffer, int slaveIndex, USB_Comm.CB cb_spec, int crType)
{}
However, I'm getting compilation errors indicating it's not being seen:
CR5_new.CR5 does not implement interface member iCR.initCRData(byte[], byte[], int, USB_Comm.CB, int)
iCR.initCRData in explicit interface declaration is not a member of interface
Any thoughts? On the one had it doesn't seem to see that it's there, but then it sees it and thinks it's not a part of the interface. This is what the interface VS project looks like,
public interface iCR
{
. . .
void initCRData(byte[] wrBuffer, byte[] stBuffer, int SlaveIndex, USB_Comm.ClearBox cb, int cr_Type);
. . .
}
My iCR dll is referenced in my CR5_new VS project. It could be something really basic, since I've only programmed with VS/C# for a little over 6 months...I have more C++ experience. Thanks for all of your help. I really appreciate it.
|
|
|
|
|
MichCl wrote: My iCR dll is referenced in my CR5_new VS project.
It's easier to "test" it in a separate console-app; create the desired structure there, isolated from the rest of your app.
Does it work if the interface and consuming class are in the same project? If yes, there's a problem with the reference (check namespaces, using-clauses etc) If no, there's a problem with the syntax.
This case, I'm guessing syntax. Compare your code to the example from MSDN[^].
|
|
|
|
|
It does work if the iCR, Factory class, Cr5, and El are in the same VS project, with the USB_Comm.CR class in a separate VS project.
It's weird...when I refer to the method in my CR5 project (the one we've been discussing), VS fills in the method I'm referring to, but when I try to get it to suggest the parameters I'm supposed to supply, it's not coming up with anything.
|
|
|
|
|
MichCl wrote: It does work if the iCR, Factory class, Cr5, and El are in the same VS project, with the USB_Comm.CR class in a separate VS project.
A syntax-error would have generated a compile-error. The fact that it works implies that the code is correct, and that it's a problem with the references.
Did you reference the project (add the project-source to the solution) or the assembly? Is there an old version of this assembly in the GAC?
Alternatively; what happens if you rename the interface? Does the exception pick up the correct new interface-name?
|
|
|
|
|
I figured it out... See below, after my response to your last post.
There are compilation errors with the VS project distributed as I first presented it. It's
CR5_new.CR5 does not implement interface member iCR.initCRData(...) (but it does)
and
iCR.initCRData in explicit interface declaration is not a member of interface (but it is)
I have a reference to the VS project iCR in my CR5_new project.
I'm not sure what you're referring to with GAC above. When I look in my CR5_new project, even though I see it referenced in the solution explorer under references, when I look in MyComputer, I don't see a copy of the dll, so presumably it's not a copy, it's actually looking for it in the original location. When I look at the Solution Explorer properties of iCR, it's giving the path to the correct original location for the dll.
Alternatively, when I change the name of the interface to iC from iCR, I had to change it in
public class CR5:iC in my CR5_new namespace/visual studio project. Plus I had to change it to iC.initCRData(...). Then the above compile errors changed to use the new interface name.
I figured it out when I was looking into the above... My CR5 project had another class in it for USB_Comm.CB. The iCR was also referring to this class for parameters in the interface. So they were cross-referencing. So I moved the USB_Comm.CB class into it's own VS project so they can both refer to it without cross-references.
On the one hand I feel like I'm not using multiple class VS projects, but if I kept these things in them, I'd have repeats of classes in my VS projects like El. Plus when I create my CR6 project, I can re-use code more. Thanks for all of your help!!
|
|
|
|
|
MichCl wrote: I figured it out... See below, after my response to your last post.
Whehe, cool - and good explanation!
|
|
|
|
|