Reputation: 224089
I'm a C# newbie, so please bear with me.
OK, so I have two classes in different assemblies that need to reference each other:
namespace AssemblyA
{
class A
{
private B MyB { get; set; }
}
}
namespace AssemblyB
{
class B
{
private A MyA { get; set; }
}
}
I understand that circular references aren't allowed, so I'm using an interface:
namespace AssemblyA
{
public interface IB
{
// whatever 'A' needs of 'B'
}
class A
{
private IB MyB { get; set; }
}
}
namespace AssemblyB
{
class B : AssemblyA.IB
{
private A MyA { get; set; }
}
}
This works, but it has the disadvantage that it exposes IB
to the rest of the world. What I would like to do instead is to make IB
internal
. But then B
cannot derive from it.
In C++, I'd make B
a friend and be done. I understand that C# doesn't have friends (pun not intended, but noted), so I have to make do without. I've read that there is an attribute for that, but this will make the whole of assembly A
accessible to the whole of assembly B
, which I don't like. Is there a way to avoid that?
Upvotes: 2
Views: 1067
Reputation: 37850
It seems that the big issue here is letting assembly B see one specific member of assembly A.
This negates, according to the comments reiterating part of the original question, the feasibility of using the well-documented InternalsVisibleTo
attribute.
Or does it?
Have you considered making a new assembly, C, with the IB
interface marked internal
and its own InternalsVisibleTo
attributes out to A and B?
This at least exposes IB in a controlled fashion, without exposing all of A to B. I'm not a huge fan of the solution (I would personally just go ahead and use InternalsVisibleTo
on A as has been suggested, then document the rest of my internals to keep others in line), but I understand where you're coming from -- and this at least solves the problem.
Upvotes: 4
Reputation: 147370
You've in fact been misinformed - C#/.NET does indeed have support for friend assemblies. You want to mark your two assemblies as Friend Assemblies, which MSDN defines as the following:
An internal type or internal member in an assembly can be accessed from another assembly.
So, simply place the following attribute anywhere in one of your code files in your project (I would choose AssemblyInfo.cs
).
[assembly:InternalsVisibleTo("name_of_friend_assembly")]
Upvotes: 8