Solved

Advanced problem...

Posted on 2004-10-24
273 Views
Last Modified: 2012-06-27
Hello

I have a big problem that i dont know how to solve.
Heres a brief description:

I have a main app where i have an enum that is named Countries,
it looks something like:

public enum Countries
{
    Canada = 1,
    Australia = 2,
    Japan = 3
}

I am using this enum in my main app.
In my main app i also have a referense to a dll thats in my solution as its own project.

In this dll i have another class thats also using the enum.
Because of this i have the declaration here too.

So now comes my problem.
If i change my enum in my main app the dll wont work since it could differ in the declaration of the enum Countries.

What i want to do is have my main-app with the declaration of countries.
The dll should know that in its class it have a enum but it should not know how it looks, and when i create the dll-class from my main app i want to tell it how the enum looks like.

Is that possible?

I want to be able to have the declaration on 1 place only and from the place where i have my declaration i want to be able to tell the dll-class how the enum looks like.

I know i could fix THIS problem with another dll where i have the declaration as a public enum which both classes use.
But this is only 1 way to look at my problem.

I want to be able to tell the class later on how a declaration looks like.

Something like this kind of pseudo-code:

class1{
    public <Unknown> mycountries;  //I dont know yet how this will look like
    public void setDeclaration(ref Unknown u){
        mycountries = u;   //Tell me how the enum looks like
    }
    public void test()
    {
        if(1 == mycountries.Japan){   //I know that Japan always will be in this enum
        }
    }
}

class2{
    public enum Countries{
        Canada = 1,
        Australia = 2,
        Japan = 3
    }

    public Class1 test;
    public class2()
    {
        test = new Class1();
        test.setDeclaration(ref this.Countries);  //Tell class1 how the enum is built
        test.test();
    }
}


Is this even possible?
I would be soooo thankful if anyone knew how this could be done!

Thanks
/Dj
0
Question by:iamdj
    13 Comments
     
    LVL 2

    Expert Comment

    by:derekthornton
    From the way you're making it sound, the .dll is not written in C#. That's my first assumption, anyway. Let me see if I understand correctly.

    You have a .dll that contains a 'Countries' Enumeration. (it is an enum, correct) but it's empty.

    public enum Countries { }

    you do not wish for the Countries enum to be declared at design time until you specify it in your code at a later point?  So you want Countries to remain empty until a later class, which actually gives it the values. I've got some ideas, please tell me if I understand your problem correctly.

    Just out of curiosity, what purpose does that serve? I'm sure it has some, I just don't see it, it seems like an interesting way to do something...
    0
     
    LVL 8

    Expert Comment

    by:Razzie_
    From what I understand the name of the enum, 'Countries', can change? To the best of my knowledge, it is then not possible to add a reference to the enum if you don't know its name.

    But maybe I misunderstoood :)
    0
     
    LVL 2

    Expert Comment

    by:derekthornton
    Hrnm ...It sounds to me that Reflection is the answer we're looking for.

    What you may want to do is something like this ..


    // --- DLL Class ----

    using System;
    using System.Reflection;

    public class DllClass
    {
     public enum Countries { } // do not declare 'countries' here, but rather just make it exist
     
     public DllClass()
     {
       // ....
     
      // Construct an Assembly Reference
      AssemblyName DefinedAssemblyName = new AssemblyName();
      DefinedAssemblyName.Name = "[NameOfYourAssembly]";

     // Dynamically Create the Assembly
     AssemblyBuilder BuiltAssembly = Thread.GetDomain().DefineDynamicAssembly
                      (Assembly.GetExecutingAssembly().GetName(),AssemblyBuilderAccess.Save);
     // Create a Module
     ModuleBuilder BuiltModule = BuiltAssembly.DefineDynamicModule("EnumerationModule","EnumerationModule.mod");

     // Define an Enum in the Assembly
     EnumBuilder CountriesEnumBuilder = DefineEnum("[Namespace].Countries",
                                               TypeAttributes.Public, typeof(Int32));
     // Declare the Three Enum Fields
     FieldBuilder EnumFieldCanada = CountriesEnumBuilder.DefineLiteral("Canada", 1);
     FieldBuilder EnumFieldAustralia  = CountriesEnumBuilder.DefineLiteral("Australia ", 2);
     FieldBuilder EnumFieldJapan = CountriesEnumBuilder.DefineLiteral("Japan", 3);
     }
    }
    0
     
    LVL 2

    Expert Comment

    by:derekthornton
    The Above code creates a new "Countries" Enum from Reflection.
    0
     

    Author Comment

    by:iamdj
    Hmm i will try to explain some more...
    The name Countries will never change, just the declaration of the enum object "Countries"

    I had 2 problems that i though i could solve if i got the solution here.. now i think i onlu need help on 1 problem.

    What i am actually trying to do is this:

    I have 1 main app and a couple of dll-files.
    When the app starts it checks againt a server to see if the dll are up-to-date, if not it replaces the local copies with the new dlls.

    So if i now for some reason want to add anther country to my enum "Countries" i would like to change the declaration in 1 dll file.
    I have now solved this by adding another dll called Declarations where i declare the Countries enum and the other dll-classes uses that declaration so when i change in the Declaration-dll all the other will automatically get the new countries i have added.

    If anyone have a better solution i would really like to hear it.

    Problem 2:


    I have a class called root that i create just when the app starts.
    And when i load a new class i send a reference to the root object so that the new class can access the root object.
    Under the root class i have my info that i want to access all over my app.

    *******************************************************
    Some pseudo-code:

    ---in dllfile 1---
    class rootClass{
        public string server_ip;
        public int server_port;
        public socketClass socket;
        private rootClass root;

        public void setRoot(ref rootClass root)
        {
            this.root = root;
            this.socket = new socketClass(ref rootClass this.root);
        }
    }

    ---in dllfile 2----
    class socketClass{
        private rootClass root;
        public socketClass(ref rootClass root)
        {
            this.root = root;
        }

        public void connect()
        {
             some_socket.connect(root.ip, root.port);
        }

        public void sendData(string data)
        {
            some_socket.senddata(data);
        }
    }
    -----

    ----in main app---
    app_start:

    public rootClass root = new rootClass();
    root.setRoot(ref rootClass root);
    root.socket.connect();

    *******************************************************

    So some explanation:

    I have 1 class in 1 dll called root, where my root object is.
    In another class in another dll i have my socketClass that have all my socket functions.

    But the problem is my circular reference.
    I want the socketClass to be under the root object so in the socketClass i need to specify how root looks like.
    And in the root object i need to tell how the socket object looks like.

    So then i though cant i in the socket.dll tell that the root object is unkown and then when i create the socketClass from my rootClass i tell the socket.dll how rootClass is declared?

    Maybe this is just a stupid solution?

    The meaning of the root class is that i would like to have an easy way to access all my classes from one place.
    Maybe i dont really need a solution as much as a better way to do it?

    Sorry for so much text in this comment.

    /dj
    0
     
    LVL 2

    Expert Comment

    by:derekthornton
    You should just be able to declare socket as a subclass of root.

    class root
    {
     class socket
     {
     }
    }

    and you can do circular referencing. I do it all the time.
    0
     
    LVL 2

    Expert Comment

    by:derekthornton
    Another way I would suggest to do it is to not have so many .dlls if you don't need to. One thing I oftentimes do is create a Global Class that will contain static existences of all of my classes that may be needed by other classes, that I don't want to pass around a lot.

    public class GlobalClass
    {
     private static class1 _class1instance;
     
     public static Class1 Class1Instance
     {
      get { ; } set { ; }
     }
    }
    0
     
    LVL 2

    Expert Comment

    by:derekthornton
    However if you still have to have them all as seperate .dll files, you an still use Reflection to accomplish this task. You'd want to create a type using Reflection that Mirrored the Root/Socket classes in each of the corrosponding .dlls, but used a .dll as a reference to build the class using MethodBuilder, ConstructorInfo, etc. This is just a case of complex late binding.
    0
     
    LVL 2

    Expert Comment

    by:derekthornton
    I'll try to get you an example of how to do what you want using Reflection here in a bit. I've got to go somewhere for about an hour.
    0
     

    Author Comment

    by:iamdj
    thanks for all the answers!

    derekthornton:
    Hmmm Reflection seems a bit hard way to do it...
    For now my project is kind of small but when i have built everything i want it will be pretty much code, so it would like to keep all components of my project in different dlls.
    But when i use circular references everything works great...except then something goes wrong in 1 of the 2 dlls.

    Just earlier today i got a problem in my socket dll.
    And when i fixed the problem i tried to build it, but now i got errors in my rootClass since its reference is pointing to my error-dll.
    So i couldnt build the socket dll since i needed the root-dll as a reference, but the root-dll referenced the socket-dll so i couldnt build that one neither.

    Ended up with that i had to commen out the socketclass from the rootclass, build the root.dll then build the socket.dll and then uncomment the socket from the rootclass and then build the new root.dll

    Seemed like a lot of trouble just for 1 bug....


    The main reason for using so many dlls is that when i find a bug in my program i want to be able to fix it and then force everyone that uses my app to upgrade when they start the program.
    And i dont want them to have to download 1 superdll that could be several mb, so i though it would be better to place every block in my app in its own seperate dll to make an upgrade speedy with small dlls, so that even users with modems can be able to upgrade.

    Maybe there is a better way there too?
    I will try to read up on circular references, cant be possible to get all the problems for 1 bug..

    Thanks for all your help!
    /Dj

    0
     
    LVL 2

    Expert Comment

    by:derekthornton
    You can build circular references, it's just very difficult to do with Visual Studio as your designer.
    0
     
    LVL 2

    Accepted Solution

    by:
    Quite frankly, unless your class has some seriously large resources or built in images, there's no way it's going to be too big if it's as small a class as you say it is. I've got two .dll files that each contain about 92,000+ lines each, and compiled they're only a few kb.
    0
     

    Author Comment

    by:iamdj
    Thanks for all ideas, i will give you full credit for it.
    I think i can fix the problem now.

    Thanks!

    /Dj
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

     Java Android Coding Bundle

    Whether you're an Apple user or Android addict, learning to code for the Android platform is an extremely valuable, in-demand skill. It all starts with Java, the language behind the apps and games that make Android the top platform it is today.

    Suggested Solutions

    Article by: Najam
    Having new technologies does not mean they will completely replace old components.  Recently I had to create WCF that will be called by VB6 component.  Here I will describe what steps one should follow while doing so, please feel free to post any qu…
    Introduction Although it is an old technology, serial ports are still being used by many hardware manufacturers. If you develop applications in C#, Microsoft .NET framework has SerialPort class to communicate with the serial ports.  I needed to…
    This video is in connection to the article "The case of a missing mobile phone (https://www.experts-exchange.com/articles/28474/The-Case-of-a-Missing-Mobile-Phone.html)". It will help one to understand clearly the steps to track a lost android phone.
    In this sixth video of the Xpdf series, we discuss and demonstrate the PDFtoPNG utility, which converts a multi-page PDF file to separate color, grayscale, or monochrome PNG files, creating one PNG file for each page in the PDF. It does this via a c…

    934 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    8 Experts available now in Live!

    Get 1:1 Help Now