Pregunta

Tengo una aplicación CRUD WinForm bastante grande que tiene numerosos objetos. Persona, inscripción, plan, nota de caso, etc. . Hay más de 30 formularios que conforman la aplicación con la interfaz de usuario dividida de forma lógica. Miembro, inscripciones, planes, notas de casos, etc. .

Estoy tratando de averiguar cómo puedo crear mi Objeto de persona después de buscar en el Formulario de búsqueda y pasar EL objeto a la siguiente formulario solicitado Sea lo que sea, digamos Demografía . En resumen, necesito que el objeto Person esté disponible en toda la aplicación y solo puede haber uno.

Ahora tengo una exposición CERO a los patrones de diseño, pero lo estoy intentando. He leído http://www.switchonthecode.com/tutorials/csharp-tutorial -singleton-pattern y http://www.yoda.arachsys.com /csharp/singleton.html pero quiero asegurarme de que entiendo correctamente cómo aplicar esto a mi situación.

Primero, los ejemplos indican que está accediendo a una referencia , ¿correcto? ¿Me equivoco o necesito acceder al valor ?

En segundo lugar, ¿hay algo más que deba hacer para que esté disponible a nivel mundial? ¿Acabo de declarar una instancia en cada formulario pero a través de este Patrón Singleton para no tener más de uno?

Gracias

EDITAR 1

Para aclarar, todos los objetos son objetos secundarios de Person. También, como la página de búsqueda elude a; los usuarios pueden seleccionar una currentPerson diferente. Pero solo pueden interactuar con ONE persona a la vez.

Por último, como dije que soy un infante en esto y si debería estar considerando otra cosa, un enfoque diferente, por favor dígalo y si tuviera la amabilidad de ofrecer alguna explicación de por qué, estaría muy agradecido.

EDIT 2

Basado en el comentario de Medicine Man, pensé que debía aclarar.

Primero, gracias a todos los que han contribuido hasta ahora. En segundo lugar, no sé lo primero acerca de los patrones de diseño y, ciertamente, no tengo los más débiles si se necesita uno en mi situación actual.

Si alguien tiene un método mejor, más simple o, en su opinión, más adecuado para pasar un objeto de datos de FORM a FORM a FORM, entonces DIGA.

Al final, solo necesito una forma de rastrear la información a medida que mis usuarios van de un lugar a otro. Gracias


¿Fue útil?

Solución

Puede usar el patrón Singleton para asegurarse de que solo se cree una instancia.

Sin embargo, el jurado aún está deliberando (al menos en mi opinión ) sobre si esta es una buena decisión. Hay muchas lecturas sobre SO y otros lugares sobre esto.

Me acercaría a esto desde un ángulo diferente. Haría que todos mis formularios tomen una instancia de Person en el constructor. De esa manera, cada formulario solo está siempre preocupado por su instancia de Persona.

Puede hacer esto creando una nueva clase que herede de Form y tiene un campo / propiedad / constructor para su Persona. Entonces, cualquier formulario que utilice Person puede heredar de su nueva clase.

Por supuesto, tendría que administrar la creación de su objeto Person. Incluso podrías hacer esto con un singleton. Sin embargo, el beneficio es que cada formulario no tiene que saber cómo crear una Persona o quién la creó. De esa forma, si elige aléjese del Singleton patrón , no tendría que cambiar todas sus referencias a su instancia de singleton.

EDIT:

Aquí hay un código para demostrar esto. Me tomó un tiempo lograr que el diseñador jugara bien. Tuve que agregar un constructor privado vacío en PersonForm para que el diseñador no arrojara un error.

Program.cs

static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MyDerivedForm(new Person { Name = "Hello World!" }));
        }
    }

Person.cs

public class Person
{
    public virtual string Name { get; set; }
}

PersonForm.cs

using System;
using System.Windows.Forms;

public class PersonForm : Form
{
    private readonly Person myPerson;

    protected virtual Person MyPerson 
    {
        get
        {
            return this.myPerson;
        }
    }

    private PersonForm()
    {
    }

    public PersonForm(Person person)
    {
        this.myPerson = person;
    }
}

MyDerivedForm.cs (agregue una etiqueta llamada label1)

public partial class MyDerivedForm : SingletonMadness.PersonForm
{
    public MyDerivedForm(Person person)
        : base(person)
    {
        InitializeComponent();
    }

    private void MyDerivedForm_Load(object sender, EventArgs e)
    {
        label1.Text = this.MyPerson.Name;
    }
}

Otros consejos

  

Primero, los ejemplos indican que está accediendo a una referencia, ¿correcto? ¿Me equivoco o necesito acceder al valor?

La clase a la que está accediendo es una referencia a una sola clase en la memoria. Por ejemplo, diga que su clase es:

public class Person { ... }

Si tiene un singleton de eso, tendrá una única " Persona " guardado en la memoria, con una referencia compartida a esa persona en el singleton. Cuando acceda a su persona soltera, trabajará con esa referencia, que es probablemente lo que desea. Cualquier cambio en la persona lo cambiará en todas partes.

  

En segundo lugar, ¿hay algo más que deba hacer para que esté disponible a nivel mundial? ¿Acabo de declarar una instancia en cada formulario pero a través de este Patrón Singleton para no tener más de uno?

Los Singletons se utilizan para hacer cumplir básicamente que cada vez que se usa el objeto, es el mismo objeto (cada uso es una referencia separada al objeto único en la memoria). Puede simplemente tomar el singleton en cualquier lugar que lo necesite, y simplemente funcionará.

Podrías hacer algo como esto:

public static class PersonController
{
    private static Person _Person;

    public static Person GetPerson()
    {
        if (_Person == null)
            _Person = new Person();

        return _Person;
    }
}

Esto asegurará que solo haya un objeto de persona. Obtendrá una referencia al objeto _Personal, no a una copia, por lo que cualquier cambio será al objeto individual que está esperando.

Como dice Reed, los singletons obligan a que se use el mismo objeto en toda la aplicación. Sin embargo, según su pregunta, no me parece que tenga la misma instancia de la clase de persona disponible en toda la aplicación, ya que existe el formulario de búsqueda " búsqueda " que parece que le permite cambiar la persona seleccionada actualmente.

En este caso, es posible que su singleton deba ser una clase contenedora que contenga el contexto actual de la aplicación y la persona seleccionada actualmente seleccionada. Esto puede ser algo así como:

public class Context
{
   private static Context _instance;

   public static Context Instance
   {
       get
       {
           if (_instance == null)
           {
               _instance = new Context();
           }
           return _instance;
       }
   }

   public Person CurrentlySelectedPerson { get; set; }

   private Context() { }
}

(Tenga en cuenta que este no es un patrón de singleton ideal ya que no es seguro para subprocesos ...)

Luego, el formulario de búsqueda establecería la persona seleccionada actualmente con:

Context.Instance.CurrentlySelectedPerson = personSelectedInForm;

Y el demográfico de puede usarlo como:

//Get the demographics for the current person
ShowDemographics(Context.Instance.CurrentlySelectedPerson);

También puedes usar el patrón de monostato con tu clase Person .

public class Person
{
    public Guid Id { get; set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }
}

Cree un objeto de monostato para Person .

public class CurrentPerson
{
    public static Person Person { get; set; }

    public Guid Id
    {
        get { return CurrentPerson.Person.Id; }
        set { CurrentPerson.Person.Id = value; }
    }

    public String FirstName
    {
        get { return CurrentPerson.Person.FirstName; }
        set { CurrentPerson.Person.FirstName = value; }
    }

    public String LastName
    {
        get { return CurrentPerson.Person.LastName; }
        set { CurrentPerson.Person.LastName = value; }
    }
}

Ahora puedes inicializar el monostato.

CurrentPerson.Person = GetPersonByUserInput();

Y luego use CurrentPerson en todo el código y todos accederán a un estado compartido común.

CurrentPerson currentPerson = new CurrentPerson();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top