C# 注册到";这";对象';s自己的事件处理程序在“中”;这";方法
我想为“Authenticator”(以下简称“objAuthenticator”)实例生成的事件提供deafult实现 这是一种可接受的做法,提供这样一种方法,即注册以处理objAuthenticator自己的事件,从而提供deafult实现 此外,如果这是一个可以接受的做法,我还有两个后续问题。 对于“SendEmailOnAuthenticationFailed”,我有两个重载方法C# 注册到";这";对象';s自己的事件处理程序在“中”;这";方法,c#,.net,events,C#,.net,Events,我想为“Authenticator”(以下简称“objAuthenticator”)实例生成的事件提供deafult实现 这是一种可接受的做法,提供这样一种方法,即注册以处理objAuthenticator自己的事件,从而提供deafult实现 此外,如果这是一个可以接受的做法,我还有两个后续问题。 对于“SendEmailOnAuthenticationFailed”,我有两个重载方法 我应该向外界透露哪一个 哪一个会减少类之间的耦合 public class Authenticator {
- 我应该向外界透露哪一个李>
- 哪一个会减少类之间的耦合
public class Authenticator { public event EventHandler AuthenticationFailed = delegate { }; protected virtual void OnAuthenticationFailed() { var handler = AuthenticationFailed; handler(this, EventArgs.Empty); } public void IsAuthenticated() { // Some logic... // ... // Woops authentication failed OnAuthenticationFailed(); } // Is this a better option? public void SendEmailOnAuthenticationFailed() { SendEmailOnAuthenticationFailed(EmailSender); } // Or is this? public void SendEmailOnAuthenticationFailed(EventHandler emailSender) { AuthenticationFailed += emailSender; } private void EmailSender(object sender, EventArgs e) { Console.WriteLine("Send email: EmailSender"); } }
public class Authenticator
{
private readonly IEmailResponder _EmailResponder;
public Authenticator(IEmailResponder emailResponder)
{
_EmailResponder = emailResponder;
}
public void IsAuthenticated()
{
// Some logic...
// ...
// Woops authentication failed
SendEmailForAuthenticationFailure();
}
private void SendEmailForAuthenticationFailure()
{
_EmailResponder.SendEmail(...);
}
}
倾听自己的事件是不寻常的;这种逻辑通常可以进入OnAuthenticationFailed方法。也就是说,我对您的代码试图做什么感到非常困惑,这使得回答有点困难
我怀疑它是否适用,但另外请注意,如果此代码是高度线程化的(大多数不是),您可能需要考虑一些微妙的问题(在谈论您自己的事件时)。我想我第一次误解了您的问题。。。我说你想要一种可选的方式来做这件事对吗?就我个人而言,我怀疑我会在构造函数中选择:
public class Authenticator
{
public event EventHandler AuthenticationFailed = delegate { };
public Authenticator(bool sendEmailOnFailure)
{
if (sendEmailOnFailure)
{
// No need for the no-op delegate any more, so just replace it.
AuthenticationFailed = EmailSender;
}
}
}
或者,将“电子邮件发送”功能从“身份验证”功能中分离出来,以便更好地分离关注点,并允许调用方使用电子邮件处理程序进行订阅(如果他们愿意)。这可能是一个更简洁的解决方案。第一个问题的答案是它是可以接受的。对于你的后续行动,答案是视情况而定。第一种方法将电子邮件过程内部化。如果您选择这样做,请确保您正在注入电子邮件逻辑。如果选择后者,则允许您注入行为。但是,如果您使用第二个名称,我建议您更改名称,因为它是电子邮件、MQ还是TiddlyLink并不重要。事实上,第二种方法其实并不需要,因为它们可以直接订阅事件 如果您关心解耦,那么需要考虑Authenticator类的单一职责。应该是认证,而不是发送电子邮件。试试这个:
public class Authenticator
{
public event EventHandler AuthenticationFailed = delegate { };
protected virtual void OnAuthenticationFailed()
{
AuthenticationFailed(this, EventArgs.Empty);
}
}
现在,使用验证器:
AuthenticationEmailResponder responder = new AuthenticationEmailResponder(emailAddress, emailServer);
objAuthenticator.AuthenticationFailed += responder.SendFailureMessage;
不,他们不能那样做。AuthenticationFailed是一个事件-它不能从类内的任何位置分配(在类中,相同的名称实际上指的是字段)。“如果您选择这样做,请确保您正在注入电子邮件逻辑”->是的,我实际上是通过构造函数注入emailer对象,上面的代码只是我在一分钟内组装的一个演示代码。这很好。如果您的业务用户希望在电子邮件之上添加其他通知方法,那么您仍然面临耦合问题。最好使用一个比电子邮件更通用的术语。无论这种做法是否可以接受,我决定现在不公开这个事件。它不见了。不需要保留死代码。谢谢。事实上,我是在问听它自己的对象的事件是否是一种可接受的做法,或者不是,甚至是通常的做法。如果是的话,我不知道如何向外界公开自我事件注册。