0

ここで長いコードを許してください。これはオブジェクト指向開発者にとって非常に基本的な基本的な質問かもしれませんが、私は.NETの最深部にいるフロントエンド開発者であり、クラスとメソッドについて学ぼうとしています。実際の例で。私はこのことを説明するためのリソースを読みましたが、すぐに実際のコードの複雑さに行き詰まります。

基本的に、Webページにコメントを追加し、ステータスを操作するための方法がたくさんあります(スパムとしてマークする、削除するなど)。これらのメソッドの多くは「EmailNotification」メソッドを呼び出します。このメソッドは、各段階で管理者に電子メールを送信します。それは素晴らしい働きをします。

ただし、プロジェクトの他の場所で「EmailNotification」メソッドを使用して、別の.csファイルから呼び出したいと思います。これを実行しようとすると、メソッドが認識されません。これは、(私が思うに!?)パブリック静的メソッドではないためです。

誰かがEmailNotificationメソッドを抽出して、コードのさまざまな場所で使用できるようにする方法を説明できますか?このメソッドを含む新しいクラスを作成しようとしましたが、機能させることができません。

using System;
using System.Net.Mail;

namespace UComment.Domain
{
public class Comment
{
    public delegate void CommentCreatedEventHandler(Comment sender, EventArgs e);
    public delegate void CommentDeletedEventHandler(Comment sender, EventArgs e);
    public delegate void CommentSpamEventHandler(Comment sender, EventArgs e);
    public delegate void CommentApprovedEventHandler(Comment sender, EventArgs e);

    public static event CommentCreatedEventHandler CommentCreated;
    public static event CommentDeletedEventHandler CommentDeleted;
    public static event CommentSpamEventHandler CommentSpam;
    public static event CommentApprovedEventHandler CommentApproved;

    protected virtual void OnCommentCreated(EventArgs e)
    {
        if (CommentCreated != null) CommentCreated(this, e);
    }

    protected virtual void OnCommentSpam(EventArgs e)
    {
        if (CommentSpam != null) CommentSpam(this, e);
    }

    protected virtual void OnCommentApproved(EventArgs e)
    {
        if (CommentApproved != null) CommentApproved(this, e);
    }

    protected virtual void OnCommentDelete(EventArgs e)
    {
        if (CommentDeleted != null) CommentDeleted(this, e);
    }


    public int Id { get; set; }
    public int ParentNodeId { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Website { get; set; }
    public bool Spam { get; set; }
    public bool Approved { get; set; }
    public DateTime Created { get; set; }
    public string CommenText { get; set; }
    public int StatusId { get; set; }

    public Comment(int id)
    {
        Id = id;
        var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
        var reader = sqlHelper.ExecuteReader("select * from Comment where id = @id",
                                             sqlHelper.CreateParameter("@id", id));

        if(!reader.HasRecords) throw new Exception(string.Format("Comment with id {0} was not found", id));

        reader.Read();

        Name = reader.GetString("name");
        ParentNodeId = reader.GetInt("nodeid");
        Email = reader.GetString("email");
        Website = reader.GetString("website");
        Approved = reader.GetBoolean("approved");
        Spam = reader.GetBoolean("Spam");
        Created = reader.GetDateTime("created");
        CommenText = reader.GetString("comment");
        StatusId = reader.GetInt("statusid");
    }

    private Comment()
    {
    }

    /// <summary>
    /// Set as approved, mark as Not Spam - ignore HAM status
    /// </summary>
    public void MarkAsApproved()
    {
        var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
        sqlHelper.ExecuteNonQuery(
             "update comment set approved = 1, spam = 0, statusid = 2 where id = @id",
             sqlHelper.CreateParameter("@id", Id));

        OnCommentApproved(EventArgs.Empty);

        // Send approval email
        EmailNotification(1);

    }

    /// <summary>
    /// Remove approval status. Ignore Spam and Ham states
    /// </summary>
    public void MarkAsNotApproved()
    {
        var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
        sqlHelper.ExecuteNonQuery(
             "update comment set approved = 0, statusid = 3 where id = @id",
             sqlHelper.CreateParameter("@id", Id));

        OnCommentApproved(EventArgs.Empty);

        // Send rejection email
        EmailNotification(2);
    }



    /// <summary>
    /// Spam cannot be ham or approved
    /// </summary>
    public void MarkAsSpam()
    {
        var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
        sqlHelper.ExecuteNonQuery(
             "update comment set spam = 1, ham = 0, approved = 0, statusid = 3 where id = @id",
             sqlHelper.CreateParameter("@id", Id));

        OnCommentSpam(EventArgs.Empty);

        // No email notification required - spammer not worthy of a reason for rejection
    }


    /// <summary>
    /// Ham is "not spam" - approved comments from Akismet. 
    /// </summary>
    public void MarkAsHam()
    {
        var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
        sqlHelper.ExecuteNonQuery(
           "update comment set spam = 0, ham = 1 where id = @id",
           sqlHelper.CreateParameter("@id", Id));

        // No email notification required, simply marking spam as ham
    }

    public void Delete()
    {
        if (Id < 1) return;

        var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
        sqlHelper.ExecuteNonQuery("delete from comment where id = @id", sqlHelper.CreateParameter("@id", Id));

        Id = -1;
        OnCommentDelete(EventArgs.Empty);

        // Permanent deletion
    }

    public void Reject()
    {
        if (Id < 1) return;

        var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);
        sqlHelper.ExecuteNonQuery("update comment set statusid = 3 where id = @id", sqlHelper.CreateParameter("@id", Id));

        //Id = -1;
        //OnCommentDelete(EventArgs.Empty);

        // Send rejection email
        EmailNotification(2);
    }




    public static Comment MakeNew(int parentNodeId, string name, string email, string website, bool approved, bool spam, DateTime created, string commentText, int statusId)
    {

        var c = new Comment
            {
                ParentNodeId = parentNodeId,
                Name = name,
                Email = email,
                Website = website,
                Approved = approved,
                Spam = spam,
                Created = created,
                CommenText = commentText,
                StatusId = statusId
            };

        var sqlHelper = DataLayerHelper.CreateSqlHelper(cms.GlobalSettings.DbDSN);

        c.Id = sqlHelper.ExecuteScalar<int>(
            @"insert into Comment(mainid,nodeid,name,email,website,comment,approved,spam,created,statusid) 
                values(@mainid,@nodeid,@name,@email,@website,@comment,@approved,@spam,@created,@statusid)",
            sqlHelper.CreateParameter("@mainid", -1),
            sqlHelper.CreateParameter("@nodeid", c.ParentNodeId),
            sqlHelper.CreateParameter("@name", c.Name),
            sqlHelper.CreateParameter("@email", c.Email),
            sqlHelper.CreateParameter("@website", c.Website),
            sqlHelper.CreateParameter("@comment", c.CommenText),
            sqlHelper.CreateParameter("@approved", c.Approved),
            sqlHelper.CreateParameter("@spam", c.Spam),
            sqlHelper.CreateParameter("@created", c.Created),
            sqlHelper.CreateParameter("@statusid", c.StatusId));

        c.OnCommentCreated(EventArgs.Empty);

        if (c.Spam)
        {
            c.OnCommentSpam(EventArgs.Empty);
        }

        if (c.Approved)
        {
            c.OnCommentApproved(EventArgs.Empty);
        }

        return c;
    }

    public override string ToString()
    {
        return @"ParentNodeId " + ParentNodeId + @"
        Name " + Name + @"
        Email " + Email + @"
        Website " + Website + @"
        Approved " + Approved + @"
        Spam " + Spam + @"
        Created "+ Created + @"
        CommenText " + CommenText + Environment.NewLine;
    }


    /// <summary>
    /// Send email notification
    /// </summary>
    public void EmailNotification(int notificationType)
    {

        var uCommentAdminEmail = Config.GetUCommentSetting("uCommentAdminEmail");

        MailAddress to = null;
        MailAddress from = new MailAddress(uCommentAdminEmail);
        string subject = null;
        string body = null;

        switch (notificationType)
        {
            case 1:
                // Comment approved
                to = new MailAddress("me@mydomain.com");
                subject = "Comment approved";
                body = @"The comment you posted has been approved";
                break;
            case 2:
                // Comment rejected
                to = new MailAddress("me@mydomain.com");
                subject = "Comment rejected";
                body = @"The comment you posted has been rejected";
                break;
        }

        MailMessage message = new MailMessage(from, to);
        message.Subject = subject;
        message.Body = body;
        SmtpClient client = new SmtpClient();           

        try
        {
            client.Send(message);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception caught in EmailNotification: {0}", ex.ToString());
        }
        finally
        {
            //
        }


    }


}
}

ポインタをありがとう!

4

5 に答える 5

3

あなたはできる:

  1. 静的クラスの静的メソッドに抽出します
  2. インスタンスメソッドを持つシングルトンクラスを作成します
  3. MessageSenderのクラスとインターフェイスを作成し、DIを使用して必要な場所に挿入します。

プロジェクトのサイズによって異なります。小さいものの場合は1.十分な場合があり、大きくて複雑な場合(DIが配置されている場合)は3が必要になります。

于 2012-05-29T21:38:14.923 に答える
2

あなたのクラスはあまりにも多くのものを作ります!

関心の分離に従って、それぞれが1つのタイプの問題のみを解決する必要があります。

電子メールの送信についても同じことです。EmailSenderクラス(または別の名前)を作成し、そこでSendメソッドを一元化します。

ISmtpClientFactoryまた、EmailSenderクラスに渡すインターフェイス(例)を作成して、具体的なシステムを抽象化して電子メールを送信し、テストエクスペリエンスを向上させることもできます。

実際に電子メールを送信する本番環境でのみ、テスト環境では、偽のファクトリを使用して送信をシミュレートできます。

public class EmailSender
{
    private readonly ISmtpClientFactory factory;

    public EmailSender(ISmtpClientFactory factory)
    {
        this.factory = factory;
    }

    public void Send(MailMessage message)
    {
        using (var client = factory.Create())
        {
            using (message)
            {
                client.Send(message);
            }
        }
    }
}

new EmailSender(new SmtpClientFactory()).Send(AdviceMessageFactory.Create(...));
于 2012-05-29T21:45:31.627 に答える
2

ここにあるのはパブリックメソッドですが、静的(public static void EmailNotification...)として宣言されていないため、それが存在するクラスのインスタンスを作成せずに使用することはできません。

using System;

namespace UComment.Domain
{
    public class MyOtherClass
    {
         public void MyMethod()
         {
             Comment c = new Comment();
             c.EmailNotification(1);
         }
    }
}

メソッドstaticを宣言すると、次のように呼び出すことができます。

using System;

namespace UComment.Domain
{
    public class MyOtherClass
    {
         public void MyMethod()
         {
             Comment.EmailNotification(1);
         }
    }
}

別の名前空間から使用しようとしている場合は、usingステートメントを使用するか、完全な名前空間をインラインで指定することにより、名前空間を含める必要があります。

using System;
using UComment.Domain;

namespace UComment.OtherNamespace
{
    public class MyOtherClass
    {
         public void MyMethod()
         {
             Comment c = new Comment();
             c.EmailNotification(1);
         }
    }
}

または

using System;

namespace UComment.OtherNamespace
{
    public class MyOtherClass
    {
         public void MyMethod()
         {
             UComment.Domain.Comment c = new UComment.Domain.Comment();
             c.EmailNotification(1);
         }
    }
}

これを一般的なメソッドにしたい場合は、Commentクラスから独立している必要があると考えるのは正しいです。今説明したのと同じ制限がそれを行うために適用されます。さらに、適切なusingステートメントが新しいクラスにあり、EmailNotification内の依存関係も考慮されていることを確認する必要があります。

于 2012-05-29T21:51:17.993 に答える
0

(すでに試したように)それを独自のクラスに入れて、メソッドを静的にすることができます。

この新しいクラスがEmailHelperの場合、次のようにメソッドを呼び出します。

EmailHelper.EmailNotification(1);

新しいクラスの名前空間によっては、それを使用するすべてのファイルの先頭にusingステートメントが必要になる場合もあります。

于 2012-05-29T21:38:56.530 に答える
0

(パブリック)クラスを作成し、そのメソッドを含めると、問題が発生するはずです。このメソッドは、電子メールを送信するために必要なすべてのプロパティを受け入れる必要があります。そのクラスのインスタンスを作成し、そのメソッドを呼び出すことができます。

于 2012-05-29T21:39:59.367 に答える