tags:

views:

170

answers:

4

I have a class A with a public method in C#. I want to allow access to this method to only class B. Is this possible?

UPDATE:

This is what i'd like to do:

public class Category
{
    public int NumberOfInactiveProducts {get;}
    public IList<Product> Products {get;set;}

    public void ProcessInactiveProduct()
    {
        // do things...

        NumberOfInactiveProducts++;
    }
}

public class Product
{
    public bool Inactive {get;}
    public Category Category {get;set;}

    public void SetInactive()
    {
        this.Inactive= true;
        Category.ProcessInactiveProduct();
    }
}

I'd like other programmers to do:

var prod = Repository.Get<Product>(id);
prod.SetInactive();

I'd like to make sure they don't call ProcessInactiveProduct manually:

var prod = Repository.Get<Product>(id);
prod.SetInactive();
prod.Category.ProcessInactiveProduct();

I want to allow access of Category.ProcessInactiveProduct to only class Product. Other classes shouldn't be able to call Category.ProcessInactiveProduct.

+2  A: 

You can if you make class A a private, nested class inside class B:

class B
{
    class A
    {
        public Int32 Foo { get; set; }
    }
}

Only B will be able to see A and it's members in this example.

Alternatively you could nest B inside A:

class A
{
    Int32 Foo { get; set; }

    public class B { }
}

In this case everyone can see both A and B but only B can see A.Foo.

Andrew Hare
Thanks, but they are separate (not nested) classes. I'd like to hide a method from class A, but show it (allow it) to only 1 certain class (class B). A and B are not nested.
Anon
Without nesting the types you will not be able to do this using default language constructs. You may have to consider a security-based approach (only allow access if a type "authenticates") but I believe that your need for this may betray a flaw in your design. What is the bigger picture? Maybe if you edit your post with more details I can help you find a solution :)
Andrew Hare
Andrew, I've updated the question.
Anon
+15  A: 

Place both classes in a separate assembly and make the method internal.

Henrik
+1 Haha! Nice answer! I may have over-thought my answer a bit :)
Andrew Hare
(Comment removed... I read it as seperate assemblies, as in plural)
Anthony Pegram
A: 

There is no out-of-the-box answer for your question.

If they are already in the same assembly, why not make the method internal scoped instead?

If they are in different assemblies, you can use the "friend" syntax which covers all internal methods.

Probably your best solution is to limit access to the public methods to specific assembly(ies). Which means that someone cannot just write a new assembly and go ahead an call your public methods. Given that you seem to have a domain model, it looks like you should allow this method to be called from other domain objects, but perhaps not from the business logic. This can be achieved by assigning a unique strong name to domain model DLL's.

You can restrict access to a public method to only allow it to be called by methods in assemblies satisfying a given public key. see msdn StrongNameIdentityPermission

Jennifer Zouak
A: 

You could use an Observer type of pattern, where the Category registers an interest in particular events on the Product (perhaps a ProductInactivated event?) and then handles the logic appropriately. This event-based pattern is very common and greatly reduces coupling. The Category is ultimately responsible for its own state and doesn't rely on the Product knowing something about what's containing it in order to keep the Category's state intact. The Product just tells interested clients when things have happened to it.

Another option is to refactor your Category class so that it contains or is contained by some CategoryProductServices object that encapsulates the methods that a Product would need to perform on its containing Category. In the context that creates the Categories and Products, pass the instance of this CategoryProductServices object to the Product rather than the full Category. This design keeps the interface public, but prevents your client from getting access to the services, as they can't retrieve an instance. It also loosens the tight coupling of Products to the Category class, limiting it to only those services that Products must be aware of. This leaves the Product in charge of the state, but at least limits what it needs to know/do.

Dan Bryant