Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / November 2007

Tip: Looking for answers? Try searching our database.

Dyanamically referring to an object instance

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
RSH - 30 Nov 2007 20:49 GMT
Hi,

I have a situation where I have multiple objects created from concrete
classes:

// Concrete implementations of the Abstract class ApprovalChain
MarketingApprovalChain MktgAppChain = new MarketingApprovalChain();
AccountingApprovalChain AcctAppChain = new AccountingApprovalChain();

I also have a Department enum
public enum Department
{
 Acct,Mktg
}

Armed with that information I need to pass those objects to another class
dynamically. (Im trying to avoid hardcoding the logic is a case conditional:

public class Purchase
{
   public Purchase(ApprovalChain appChain)
   {
   ...
   }

}

back to the original method:
private MarketingApprovalChain MktgAppChain = new MarketingApprovalChain();
private AccountingApprovalChain AcctAppChain = new
AccountingApprovalChain();

public void PurchaseRequisition(Department dept)
{
   Purchase purchase = new Purchase();<----- is there a way here to use the
string value of the enum to dynamically make reference to the appropriate
ApprovalChain to pass to the Purchase Class Constructor?
}

PsuedoCode: Purchase purchase = new Purchase(dept.ToString() +
"ApprovalChain");

Thanks alot!

Ron
cfps.Christian - 30 Nov 2007 21:07 GMT
Took me a minute to figure out what you wanted to do.

You're looking for the Activator.CreateInstance method.

What I would do is:

ApprovalChain appChain;
appChain = (ApprovalChain)Activator.CreateInstance([fully qualified
name] + dept.ToString() + "ApprovalChain")
Purchase purchase = new Purchase(appChain);

I'm not really up on my CreateInstance code but thats definitely what
you're looking for.  The string that you pass in has to be the fully
qualified name of the type you are defining.
RSH - 30 Nov 2007 22:03 GMT
Almost....

The only problem is that the objects already have been created and they
contain state that needs to be persisted which is handled by the class that
contains the method Im illustrating here.  I need to dynamically construct a
reference to the appropriate object (based on the deparment enum passed to
the method) and then pass the "live" object to the Purchase object.  Right
now I am using a case conditionional:

public void PurchaseRequest(int id, double amount, string description,
eGroup group)

{

Purchase purchase;

switch (group)

{

case eGroup.Marketing:

this.

purchase = new Purchase(id, amount, description, group,
marketingapprovalchain, marketingbudget);

break;

case eGroup.Accounting:

purchase = new Purchase(id, amount, description, group,
accountingapprovalchain, accountingbudget);

break;

}

}

}

But since I dont know the number of departments the system will ultimately
contain, I dont want to hardcode the references in a conditional.

Thanks!

Ron

> Took me a minute to figure out what you wanted to do.
>
[quoted text clipped - 10 lines]
> you're looking for.  The string that you pass in has to be the fully
> qualified name of the type you are defining.
Peter Duniho - 30 Nov 2007 22:27 GMT
> [...]
> But since I dont know the number of departments the system will ultimately
> contain, I dont want to hardcode the references in a conditional.

It's difficult for me to be sure I completely understand the question.  
I don't find the description very organized.  But, that said...

It seems to me that what you've got are already-existing instances of
ApprovalChain-derived classes that are somehow related to your
instantiation of the Purchase class.  It appears you may also have a
class named "Budget" that also has derived versions you're using.

Given that, you may want to consider just storing those instances in a
Dictionary<T>, so that you can easily look them up according to their
enum value.  For example:

   enum Department
   {
       Acct, Mktg
   }

   struct DepartmentObjects
   {
       public readonly ApprovalChain ApprovalChain;
       public readonly Budget Budget;

       public DepartmentObjects(ApprovalChain ApprovalChain, Budget Budget)
       {
           this.ApprovalChain = ApprovalChain;
           this.Budget = Budget;
       }
   }

   static Dictionary<Department, DepartmentObjects> dictDepartments;

   // run once somewhere (e.g. static constructor for whatever class
   // contains the "dictDepartments" object)
   foreach (Department dept in Department.GetValues())
   {
       switch (dept)
       {
       case Acct:
           dictDepartments.Add(dept, new DepartmentObjects(new
AccountingApprovalChain(), new AccountingBudget()));
           break;
       case Mktg:
           dictDepartments.Add(dept, new DepartmentObjects(new
MarketingApprovalChain(), new MarketingBudget()));
           break;
       }
   }

   // then wherever you need to match the enum to an instance, something
   // like this:

   Department dept = // initialized however...;

   ApprovalChain approval = dictDepartments[dept].ApprovalChain;

   // Or you could do this:
   DepartmentObject do = dictDepartments[dept];
   Purchase purchase = new Purchase(id, amount, description, dept,
do.ApprovalChain, do.Budget);

etc.

Note that at some point you do need to hardcode the relationship
between your enum and the class each value represents.  Depending on
the actual names you've used for things it certainly is possible to use
reflection to even automate that, but it seems to me it wouldn't really
buy you much.  It's not like you can just go adding new ApprovalChain
and Budget objects without visiting the code that uses those objects
and verifying you've done everything right anyway (or at least you
ought to be).

Pete
RSH - 30 Nov 2007 22:32 GMT
Peter,

Thanks!  Good stuff...that worked perfectly!

I agree that at some point I need to hardcode the names, but I wanted to do
it in one place only.  Your solution will provide me that.

thanks!
Ron

>> [...]
>> But since I dont know the number of departments the system will
[quoted text clipped - 73 lines]
>
> Pete
Mattias Sjögren - 30 Nov 2007 22:23 GMT
>PsuedoCode: Purchase purchase = new Purchase(dept.ToString() +
>"ApprovalChain");

How about a simple mapping table?

Dictionary<Department, ApprovalChain> map = new Dictionary<Department,
ApprovalChain>();
map.Add(Department.Acct, AcctAppChain);
map.Add(Department.Mktg, MktgAppChain);

...

Purchase purchase = new Purchase(map[dept]);

Mattias

Signature

Mattias Sjögren [C# MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.