tags:

views:

237

answers:

1

Hello,

In one of my previous questions I explained about a form class that contain form field objects to save data in a user profile object (using profile provider).

The code is here bellow. Basically what I would like to accomplish is to pass as a parameter to my form field objects the field of the Profile object that they should interact in order to save the data later on.

You can see that in the following line:

//LastNameFormLine is an control that was added to my form page.
//The ProfileField parameter stores the field of the UserProfile object that is being manipulated by this control
LastNameFormLine.ProfileField = "UserProfile.LastName";

I was reading about reflection to be able to save this value in the UserProfileVisitor class, but I came across this concept of delegate in C# which I am not sure yet if I fully grasp.

Is it possible to delegate the ProfileField to a property on my UserProfile class? Or should I forget about it and go with reflection?

What would you suggest?

public partial class UserProfileForm : CustomIntranetWebappUserControl
{
    protected override void OnInit(EventArgs e)
    {
        //AutoEventWireup is set to false
        Load += Page_Load;
        CancelLinkButton.Click += CancelButtonClickEvent;
        SaveLinkButton.Click += SaveButtonClickEvent;
        base.OnInit(e);
    }

    private void SaveButtonClickEvent(object sender, EventArgs e)
    {
        VisitFormFields();
    }

    private void VisitFormFields()
    {
        var userProfileVisitor = new UserProfileVisitor();

        foreach (var control in Controls)
        {
            if (control is FormFieldUserControl)
            {
                var formField = (FormFieldUserControl) control;
                formField.Visit(userProfileVisitor);
            }
        }
        userProfileVisitor.Save();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            BindText();
        }
    }

    private void BindText()
    {
        LastNameFormLine.LabelText = string.Format("{0}:", HomePage.Localize("Last Name"));
        LastNameFormLine.InputValue = UserProfile.LastName;
        LastNameFormLine.IsMandatoryField = true;
        LastNameFormLine.IsMultilineField = false;
        LastNameFormLine.ProfileField = "UserProfile.LastName";
        //... the rest of this method is exactly like the 4 lines above.
    }
}

public abstract class FormFieldUserControl : CustomIntranetWebappUserControl
{
    public string ProfileField { get; set; }
    public abstract void Visit(UserProfileVisitor userProfileVisitor);
}


public partial class FormLineTextBox : FormFieldUserControl
{
//...  irrelevant code removed... 

    public override void Visit(UserProfileVisitor userProfileVisitor)
    {
        if (userProfileVisitor == null)
        {
            Log.Error("UserProfileVisitor not defined for the field: " + ProfileField);
            return;
        }
        userProfileVisitor.Visit(this);
    }
}

public class UserProfileVisitor
{

    public void Visit(FormLineTextBox formLine)
    {
        // The value of formLine.ProfileField is null!!!
        Log.Debug(string.Format("Saving form field type {1} with profile field [{0}] and value {2}", formLine.ProfileField, formLine.GetType().Name, formLine.InputValue));
    }

    // ... removing irrelevant code... 

    public void Save()
    {
        Log.Debug("Triggering the save operation...");
    }
}
+1  A: 

Delegates are not for properties. However, Reflection is slow, may have issues with code security and it's not typesafe and may lead to runtime instead of compile-time problems on naming errors due to the late-bound nature.

That said, you may want to use getter and/or setter methods and use delegates on those.

Lucero
You Can go with properties and anonymous methods if you don't wanna have getters/setters
Rune FS