2

I would like to create a library consisting of two layers, lets call them A and B. There should be a class "Sample" in layer A. Layer B also knows about class "Sample" and enlarges it by some methods.

Then I would like to have another project, referencing this library, so I can have the following scenarios for an instance of "Sample", lets call it sample_instance:

1) using A;

Typing "sample_instance.", Intellisense will show me all the methods that are defined in layer A.

2) using B;

Typing "sample_instance.", Intellisense will show me all the methods that are defined in layer B.

3) using A;
   using B;

Typing "sample_instance.", Intellisense will show me all the methods that are defined in layer A and B.

I've been thinking about this many days now but I'm not able to find a proper solution. I've been experimenting with extension methods in layer B, which gets Scenario 1) and 3) to work. But I can't realise 2) this way, because the project doesn't know the class "Sample" if I only do "using B".

Does someone have a good idea, how to design it?

  • 2
    If the user wants to user layer B, is he supposed to not know that layer A exists? What goals are you trying to achieve with this design? Maybe you need an additional basic module that defines a very raw Sample class. Then, A and B are siblings in the dependency graph referencing on the basic module. – usr Jan 30 '16 at 13:21
  • He knows about layer A and B but can choose which one he wants to use. So layer A provides a basic set of methods, layer B a higher level. But he should also be able to use both if he wants. What do you mean by siblings, two different classes, inheriting from the base module? – GreenTree Jan 31 '16 at 13:46
  • 1
  • Why do you bother what Intellisense is showing you? It is means to help development, not drive it. It should be compiler who makes sure that A functionality can only be called when A layer is referenced and same for B. – Euphoric Jun 7 '16 at 11:23
1

Extension methods should do the trick. You can get Scenario 2 to work by redefining your Sample class in the second layer through inheritance. Something like

namespace A
{
    public class Sample { ... }

    public static class SampleExtensions 
    {
        public static void Foo(this Sample sample, ...) { ... }
        ...
    }
}

namespace B
{
    public class Sample : A.Sample { ... }

    public static class SampleExtensions 
    {
        public static void Bar(this Sample sample, ...) { ... }
        ...
    }
}

That way, using A; should show you all the methods defined in A.SampleExtensions and A.Sample, using B; should show you all the methods defined in B.SampleExtensions and B.Sample (and by inheritance A.Sample) and using A; using B; should show you all of them.

Note that the latter introduces an ambiguity on the type name Sample which can be resolved by either adding using Sample = A.Sample or by defining the Sample class in a different namespace altogether.

Also, depending on your requirements it might be wise to define the extension methods in B.SampleExtensions to extend the type A.Sample instead of Sample (which is B.Sample), that is

public static void Bar(this A.Sample sample, ...) { ... }

Otherwise an instance of A.Sample can't use an extension method defined in B.SampleExtensionseven with using B;

0

Sounds like you should think about using inheritance...

  1. Make class A the parent, and it contains one public instance sample_instance.

  2. Make classes B and C the children, so they will inherit the public instance sample_instance.

Note: In-turn, intellisense will show you the public sample_instance as a member of classses A, B, and C.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.