views:

133

answers:

4

Hi - I am having a problem setting up the following in Visual Studio 2008: a parent project which includes the entrypoint Main() method class and which declares an interface, and a child project which has classes that implement the interface declared in the parent project.

I have specified that Parent's Output type is a Console application, and Child's Output type is a Class library. In Child I have add a reference to the Parent as a project, and specified that Child depends on Parent and that the build order should be Parent, then Child.

The build succeeds, and as far I can tell, the right things show up in the Child/bin/debug directory: Parent.exe and Child.dll.

However, if I run Parent.exe, then at the point when it should load a class from the Child.dll, it fails with the error message:

exception executing operation System.TypeLoadException: Could not load type 'Child.some.class' from assembly 'Parent, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

I guess I'm confused as to how to get the Parent and Child projects to play together. I plan on having more child projects that use the same framework that is set up in the Parent, and so I do not want to move the entrypoint class down into the Child project. If I try to specify that the Child project is also a Console application, then the build process fails because there is no Main() entrypoint class in the child (even though the Parent project is included as a reference).

Any help would be welcome! Thanks, Martin

+2  A: 

Generally you want to reverse your hierarchy: your .exe project should depend on your satellite assembly projects (what you're calling "Child"). Then, to use the types in your satellite assembly, you want to add a reference from your .exe project to your assembly project. Do this by right-clicking the .exe project in the Solution Explorer of VS, then do Add Reference ... click the Projects tab and choose the assembly project.

Edit: If you want to setup a "framework" for the overall project (either by defining interfaces or base classes) then I'd start by doing so in a single, core assembly; put those definitions in something like MyProject.Core.dll. Then your "implementing" projects / assemblies would have a reference to your MyProject.Core project. With all this said, you maybe looking for something like an IOC / DI framework. See Ninject, StructureMap, Castle Windsor, etc.

xanadont
A: 

You want to avoid circular dependencies.

If you wish to keep the interface and implementasiton separate, then define the interface in a third assembly (class library) that is used by the "child" assembly (class library), then use both the interface and implementation from the application.

Jason Williams
A: 

Hi, and thanks for both these answers - they have helped me get a clearer idea of what I need to do. Here is what I did: within a single solution, I now have three projects: Application, Interface, and Implementation.

Interface: declares the interface I want to use Implementation: has the class that implements the interface Application: has the Main() method and within this method, it has a line of the form:

Type actionType = Type.GetType("ImplementationClass", true);

Both the Application and Implementation projects reference the Interface project. I can build all three projects individually, and the solution as a whole.

However, if I run debug, then here's the error I get when the application hits the GetType() line in the Main() method.

Could not load type 'ImplementationClass' from assembly 'Application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

I have tried adding the Implementation project to the Application project as a reference, but this does not work (and I want to avoid doing this anyway). Can anyone suggest what I am doing wrong?

Thanks, in advance, Martin

A: 

So in the fine tradition of answering one's own questions, I worked out that in order to call GetType() successfully, I have to specify the correct assembly. Each project is compiled into its own assembly (Application.exe, Interface.dll, and Implementation.dll). So in order to instantiate the implementation class within the Application Main() class, I have to call:

Type actionType = Type.GetType("ImplementationClass", "Implementation", true);

It seems a little hokey, but at least it works. Thanks, Martin