Protected Fields?

Mar 28, 2011 at 3:47 AM

Is it possible to mark certain entity fields as being protected rather than public? I think I could use such a capability in creating a hierarchy of classes. But it's such an obvious idea that there are probably good reasons why it's not feasible or practicable.

Coordinator
Mar 28, 2011 at 3:58 AM

Please tell me more of what you wish to do. Protected is used simply to extend a class. Well these public classes can be extended as well. I cannot think of anything you cannot do now that would be different by marked the class protected. Please tell me what you need to do.

Mar 28, 2011 at 4:14 AM

Sure. There are a couple of situations I'm running into where it feels like it would be useful.

First, it'd be a convenient way of wrapping an enum around an int field. One could imagine something like this:

protected int FieldIsReallyAnEnum { ... }

and in the partial class file:

public EnumType EnumField
{
get { return (EnumType) FieldIsReallyAnEnum; }
set { FieldIsReallyAnEnum = (int) value; }
}

Second, I think it might be useful in creating a hierarchy of classes:

public class Message // generated by nHydrate
{
protected string content { ... } 
}

and in the partial class file:

public partial class Message
{
public virtual string MessageBody 
{
get { return content; }
set { content = value; }
}
}

which would then allow me to override MessageBody in derived classes to do special processing.

Of course, I can effectively do this currently by adhering to some simple nomenclature rules. For example, I can use a rule that any property with a lower case name is to be treated as protected. But that relies on me remembering the rule :). Being able to mark a property as protected simply enforces data hiding, which is a pretty useful concept.

BTW, I know that nHydrate supports Type Tables to generate enums. But I don't find them particularly useful, mostly because of the constraints imposed on enums by the design of the .NET Framework. For example, I ran into a problem when I wanted to mark the enum generated by nHydrate as being a collection of flags. I ran into another problem when I wanted to decorate the enum field values with human-readable names, via attributes, which I could then extract at run-time to use in a UI. In the end, I found it easier to add a few tables to the database to define the enum values and then use a TT code generation file to build the enums by reading the database. Sure, that could be generalized and added to the nHydrate framework, but it's pretty application specific, so I don't think it's a good candidate for inclusion in a framework.

In any event, it's not a big deal. But I think it would be useful to be able to mark fields as protected, or even private, to the entity class which contains them. But I have no idea what implications that has for EF or database access.

Coordinator
Mar 29, 2011 at 3:23 AM

Marking fields not pubic actually causes serialization issues with EF. I do not think we are going to provide the ability to make fields non-public. However I still not understand why you need protected. That simply means you can inherit another class from the specified one. You can do this anyway with a virtual public property (as it is marked). If you want to add custom enums and such like you said you can do that whether the methods are public or protected. I guess I am just not following the thought process. You are correct in that you can not extend the enums since there is no such thing as a partial enum or extending it. However instead of doing a manually mapping the way you say, you could create a mapping method to get the "metadata" you want. Like pass the enum value in to it and it is a big switch statement with the necessary values. Either way this is custom code. I do not think we can extend the framework in the way you propose.

Mar 29, 2011 at 4:20 AM

Okay, if it can't be done because of EF, fine. No worries.

As to why... I can't make it any clearer than the first example I gave, of recharacterizing an int as an enum (since SqlServer doesn't have a native Enum type).

Sure, I can, and do, already do this:

// generated by nHydrate...
public partial class AnEntity
{
	/// <summary>
	/// The property that maps back to the database 'message.trigger' field
	/// </summary>
	/// <remarks>Field: [message].[trigger], Nullable</remarks>
	[System.ComponentModel.Browsable(true)]
	[EdmScalarPropertyAttribute(EntityKeyProperty = false, IsNullable = true)]
	[DataMemberAttribute()]
	[System.ComponentModel.DisplayName("trigger")]
	public virtual int? trigger
	{
		get { return _trigger; }
		set
		{
			Widgetsphere.EFCore.EventArgs.ChangingEventArgs<int?> eventArg = new Widgetsphere.EFCore.EventArgs.ChangingEventArgs<int?>(value, "trigger");
			if (eventArg.Cancel) return;
			ReportPropertyChanging("trigger");
			this.OnPropertyChanging("trigger");
			_trigger = eventArg.Value;
			_modifieddate = DateTime.UtcNow;
			ReportPropertyChanged("trigger");
			this.OnPropertyChanged("trigger");
		}
	}
}

// partial class file...
public partial class AnEntity
{
        // AlertTrigger is an enum, defined elsewhere
        public AlertTrigger Trigger
        {
            get { return (AlertTrigger) trigger; }
            set { trigger = (int) value; }
        }
}
But this leaves me with two publicly-visible properties, trigger and Trigger. Which is messy. If I could mark trigger as protected then the get/set methods of Trigger could refer to it, but it wouldn't be visible elsewhere in the app, reducing confusion.