Stellungnahme zum Business-Logik-Schicht-Design für Fenster und Web-basierte Anwendung

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

  •  05-10-2019
  •  | 
  •  

Frage

Ich brauche ein paar Meinungen zu der Auswahl der Signaturen für meine Web-basierte Business-Layer-Funktion:

Funktion void AngelegtVon (Firma Usercompany, string name ...)

oder

Funktion void AngelegtVon (int CompanyID, string name ...)

Wenn dies ein Fenster basierte I Funktion Objekt zu nehmen statt int wählen würde, weil da das Unternehmen bereits in das Fenster Formular geladen, warum nicht einfach nutzen. Außerdem glaube ich, Business-Schicht-Objekte Geschäft nehmen und seine Art sicher (verhindert versehentliche in 0 übergeben oder -1).

Aber auf der anderen Seite, wenn diese eine webbasierte Anwendung ist, wird nur ID Kunden-Websites geladen werden. So ist es Art von redundant Last Unternehmen Objekt, da schließlich nur wird CompanyID ohnehin im dabasebase gespeichert werden.

Hoffentlich ist meine Beschreibung nicht zu verwirrend = P Vielen Dank für das Lesen.

War es hilfreich?

Lösung

I think you answered your own question, it depends on the presentation layer you're using. But when you want to keep this business layer generic, you'll have to go with the ID.

Here's another idea. I personally like to wrap all mutations into classes, that I call commands. You could for instance have an CreateUserCommand that inherits from a base command. This would allow you to use it like this (I'm assuming C# here):

var command = new CreateUserCommand();

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

command.Execute();

When wrapping this logic in a command is very nice pattern. It allows you to put a single use case in a single command. Especially when the amount of logic in a command grows you will appreciate this pattern, but I found it to be very effective for CRUD operations as well.

This pattern also allows you to abstract the transactional model away in the base class. The base class can wrap a call to execute in a database transaction. Here is an simple implementation:

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);
}

And this is what the CreateUserCommand would look like:

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);
    }
}

I hope this helps.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top