tags:

views:

78

answers:

2

Hi,

I'm using a model UserRepository->User

The Repository is used to Save and Load the User.

I want to be able to set the ID in the Repository, but I don't want it to be access by UI.

The User and Repository are found in a Core project, and the UI in a Web.

Is there a way to do this, like a modifier for the property, or should I put the ID in the User contructor ?

Thanks

+8  A: 

You can use a property without a setter and a private variable like this:

private int _id; //Set locally
public int ID
{
  get { return _id; }
}
//in the class _id = 5;

Or use automatic properties with a private setter like this:

public int ID { get; private set; }
//in the class ID = 5; this won't work outside the class

In the second/automatic case, it's really just the compiler doing the first example, just a bit quicker and easier on the eyes.

Nick Craver
+1 Your answer was better than mine :)
Kelsey
If that applicable, you can use protected instead of private. This will work with both the first version and the automatic properties version.
Brian
@Brian - Good point, you can use the `internal` modifier as well if you wanted to expose it only in the same assembly. In that case your data layer could set it but not the UI layer in another project, etc.
Nick Craver
And in fact, I think the OP does need the internal keyword here rather than private, since Repository is setting the ID of a User and is part of the same project, unlike UI which is in a separate project.
Brian
I think internal is the best keyword that I can use. Thanks
Patrick Parent
A: 

I have used this patten (not familiar with C# as such, but the idea should work):

class Foo
{
    protected int id;

    public int GetID()
    {
        return (ID);
    }
}

class MutableFoo : Foo
{
    public void SetID(int val)
    {
        id = val;
    }
}

then the UI only deals with the "Foo" class which is read-only while other parts can deal with the "MutableFoo" which is read/write. You should be able to only ever create instances of "MutableFoo" and then pass them to other parts of the code that receives then as "Foo", this the UI code would have read-only access to the objects while other parts can have read-write access.

I'd probably make "Foo" abstract as well (I cannot think of a case where I haven't).

TofuBeer
-1: This is not the way to do it in C#.
Brian
That is so Java...
Dykam
not just Java... used it in several languages. Just so I understand, how would the C# way of properties for a class A give 2 classes (say X for read only and Y for read/write) access?
TofuBeer
You could either use the internal keyword and make Y part of the same assembly or make Y an inner class of A. If Y needs to be in a separate assembly, you could use Friend Assemblies.
Brian
ah... I hate friend in C++... I imagine it is the same in C# (off to go take a look to edumacate myself :-). I'll go look up assemblies as well - are they like a C++ namespace?
TofuBeer
The MSDN ( http://msdn.microsoft.com/en-us/library/ms228632(VS.80).aspx ) states, "An assembly in the .NET Framework equates roughly to Java's JAR file." But yeah, I generally don't consider friend assemblies to be a great thing to use. In fact, in truth the method you describe here is probably a good one, at least in some situations, but in the OP's case it's massively overcomplicated for something which has a built in solution.
Brian