1

I have a framework which contains several assemblies. Multiple assemblies was created due to logical separation of code. This framework is supposed to be distributed to developer as well as end user. Developer are supposed to use few of framework assemblies to develop their modules. But all other assemblies are required to run the modules. Out of several assemblies, I want only few assemblies could be added to project reference and restrict other from being added to developer project references. In other words, I want developer should not be able to use types contained in assemblies which are not meant for plugin development. What is the best way to do that? I want to avoid passing some object to constructor of each type in those assemblies and verify them.

Can I take advantage of AppDomain or anything similar to that, which identifies type is being created by main app or module. If it is not main app, then throw exception or don't initialize. Any change in architecture is suggested.

hungryMind
  • 6,931
  • 4
  • 29
  • 45

2 Answers2

5

One option would be to make the types within the "restricted" assemblies internal instead of public, then add InternalsVisibleToAttribute within those restricted assemblies to allow access to them from the other "framework" assemblies.

That way the end developer can still add a reference to the "restricted" assemblies (and probably should do so, in order to make sure they're copied for deployment) but won't be able to use any of the types within those assemblies.

EDIT: Another alternative might be to use ILMerge to build one assembly at the end - so it's a real unit of deployment, even though you originally split it out for separation reasons.

Yet another alternative would be to merge everything into one project and rely on code review, namespaces and common sense to pick up separation violations.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Can I avoid PublicKey in InternalsVisibleTo and allow assemblies only in application directory. – hungryMind Aug 01 '11 at 14:46
  • @hungry: Not that I'm aware of, no. But that's a one-off pain, really. – Jon Skeet Aug 01 '11 at 14:47
  • And merge all assemblies (with ILMerge) to one single assembly and ship that to your users. Don’t annoy your users with your internal architecture. It is very unpleasant for a developer to need to include many assemblies, while all the relevant types are just in one assembly. – Steven Aug 01 '11 at 14:48
  • 1
    @Steven: Ironically I'd just been editing my answer to include ILMerge :) – Jon Skeet Aug 01 '11 at 14:49
  • Attributes does not have any role in run time, so how it allows to known assemblies? Also can developer use my types using reflection? Just curious? – hungryMind Aug 01 '11 at 14:49
  • @hungryMind: What do you mean by "Attributes does not have any role in run time"? They're still available at execution time, and the CLR takes particular note of `InternalsVisibleTo`. And yes, the end-developer will be able to use reflection if they're running under full trust. – Jon Skeet Aug 01 '11 at 14:51
  • @steven, developer are supposed to use only one assembly, but I was worried if they add other as well which are private for application only not meant for modules. – hungryMind Aug 01 '11 at 14:52
  • @hungryMind: I would go with Jon's last option: Put everything in one project. You can use a tool such as NDepend to verify your framework's architecture. – Steven Aug 01 '11 at 14:56
  • How does compiler allow type to be created by known assemblies? i.e., compiler must be aware of this attribute in framework, am i right? Can I write something like InternalsVisibleTo attribute? – hungryMind Aug 01 '11 at 15:03
  • @hungryMind: Yes, the compiler has specific knowledge of this - you wouldn't be able to write something similar yourself. – Jon Skeet Aug 01 '11 at 15:04
  • Could you also put your views on http://stackoverflow.com/questions/6781876/chain-of-events-proxy-to-original-object and http://stackoverflow.com/questions/6734113/how-to-map-objects-with-ui – hungryMind Aug 02 '11 at 12:54
  • @hungryMind: I'm not really sure I have anything useful to add to those questions at the moment, I'm afraid. – Jon Skeet Aug 02 '11 at 13:00
4

You can make all of the types in the other assemblies internal to prevent them from being ued outside their defining assembly.

You can use the [InternalsVisibleTo] attribute to make them visible to your other assemblies.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964