Parere sulla logica di business layer design per la finestra e applicazione web based

StackOverflow https://stackoverflow.com/questions/3785590

  •  05-10-2019
  •  | 
  •  

Domanda

Ho bisogno di alcuni pareri sulla scelta di quale le firme per la mia funzione di strato di business basato sul web:

Funzione CreateUser void (società UserCompany, string name ...)

o

Funzione CreateUser void (int CompanyID, nome della stringa ...)

Se questa è una finestra basata avrei scelto la funzione di prendere oggetto invece di int, perché da quando la società già caricato alla forma della finestra, perché non lo utilizzano. Inoltre, penso strato di business dovrebbe prendere gli oggetti di business e il suo tipo di sicurezza (prevenzione accidentalmente passare 0 o -1).

Ma d'altra parte, se si tratta di un'applicazione web based, solo id sarà caricato ai siti dei clienti. Quindi è una specie di ridondante per oggetto sociale carico perché alla fine solo CompanyID verrà salvato nella dabasebase comunque.

Spero che la mia descrizione non è troppo confuso = P Grazie per la lettura.

È stato utile?

Soluzione

Credo che tu risposto alla tua domanda, dipende dal livello di presentazione che si sta utilizzando. Ma quando si desidera mantenere questo livello business generico, si dovrà andare con l'ID.

Ecco un'altra idea. Personalmente, come per avvolgere tutte le mutazioni in classi, che io chiamo i comandi. Si potrebbe per esempio avere un CreateUserCommand che eredita da un comando di base. Ciò consentirebbe di utilizzare in questo modo (sto supponendo C # qui):

var command = new CreateUserCommand();

command.UserCompanyId = companyId;
command.UserName = name;

command.Execute();

Quando avvolgere questa logica in un comando è molto bello modello. Esso consente di mettere un singolo caso d'uso in un unico comando. Soprattutto quando la quantità di logica in un comando cresce si potranno apprezzare questo modello, ma ho trovato per essere molto efficace per le operazioni CRUD pure.

Questo modello consente inoltre di astrarre il modello transazionale via nella classe base. La classe base può avvolgere una chiamata per eseguire in una transazione di database. Ecco un semplice implementazione:

public abstract class CommandBase
{
    public void Execute()
    {
        this.Validate();

        using (var conn = ContextFactory.CreateConnection())
        {
            conn.Open();
            using (var transaction = conn.BeginTransaction())
            {
                using (var db = ContextFactory.CreateContext(conn))
                {
                    this.ExecuteInternal(db);

                    db.SubmitChanges();
                }

                transaction.Commit();
            }
        }
    }

    protected virtual void Validate() { }

    protected abstract void ExecuteInternal(YourDataContext context);
}

E questo è ciò che il CreateUserCommand sarà simile:

public class CreateUserCommand : CommandBase
{
    public int UserCompanyId { get; set; }
    public string UserName { get; set; }

    protected override void ExecuteInternal(YourDataContext context)
    {
       this.InsertNewUserInDatabase(context);
       this.ReportCreationOfNewUser();
    }

    protected override void Validate()
    {
        if (this.UserCompanyId <= 0) 
            throw new InvalidOperationException("Invalid CompanyId");
        if (string.IsNullOrEmpty(this.UserName))
            throw new InvalidOperationException("Invalid UserName");
    }

    private void InsertNewUserInDatabase(YourDataContext context)
    {
       db.Users.InsertOnSubmit(new User()
       {
          Name = this.UserName,
          CompanyId = this.CompanyId
       });
    }

    private void ReportCreationOfNewUser()
    {
        var message = new MailMessage();
        message.To = Configuration.AdministratorMailAddress;
        message.Body = "User " + this.Name + " was created.";

        new SmtpClient().Send(message);
    }
}

Spero che questo aiuta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top