我正在实施通知服务。从本质上讲,客户可以通过多种方式获得通知,例如通过电子邮件,短信,传真等。以下是一个未连接在一起的粗略实现。
public class NotificationService
{
private readonly INotification _notification;
private readonly INotificationFormatter _formatter;
public NotificationService(
INotificationMethod notification,
INotificationFormatter formatter)
{
_notification = notification;
_formatter = formatter;
}
public void Notify(SomeParameterObject obj)
{
var formattedMessage = _formatter.Format(obj);
_notification.SendNotification(formattedMessage);
}
}
public interface INotificationFormatter
{
NotificationMessage Format(SomeParameterObject obj);
}
public interface INotification
{
void SendNotification();
}
public EmailNotification : INotification
{
public void SendNotification(NotificationMessage message)
{
// Use Exchange Web Services to send email
}
}
NotificationService
类基本上采用了通知方法和格式化程序。显然,每种通知方法都需要不同的格式。
根据业务标准,如何选择我希望使用的INotification
和NotificationFormatter
实施?请注意,在使用应用程序的用户的生命周期内,很可能会使用每个通知。我这样说是因为它并不像指示我的容器注入实现Foobar
那么简单,因为它会在用户使用应用程序时发生变化。
我曾想过创建一些可以处理对的类,因为我觉得你不想使用短信通知格式化器来传真通知。但是,我似乎无法绕过一个体面的实现。
我还拥有Mark Seemann在.NET中的Dependency Injection这本书。我可能会错过一些明显的东西吗?
谢谢。
答案 0 :(得分:4)
您如何确定用户想要的通知类型?如果它在使用您的应用时可能会发生变化,则似乎会为您要发送的每个通知重新创建该用户的NotificationService。没关系 - 只需使用某种查找来选择IoC容器的INotification impelmentation。
IoC(我使用AutoFac)允许您使用字符串索引来选择特定的实现。该字符串可以来自数据库或代表用户偏好的任何内容。然后你将它传递给你的IoC,要求用你的字符串选择'装饰'。启动时,所有各种实现都使用其选择字符串进行注册。
我认为你可能会对你的'对'评论有所了解 - 如果INotificationFormat与INotification密切相关并且有可能将它们混合起来,那么也许INotification实现本身应该选择它的格式化程序。
答案 1 :(得分:2)
您需要做的是提供某种配置基础架构。例如,假设您希望按照您定义的方式保留服务,我将根据您的模型实现返回NotificationService实例的工厂:
public struct NotificaitonSettings<T>
{
public Predicate<T> Predicate;
public NotificationService Service;
}
public class NotificationServiceFactory<T> : INotificationServiceFactory<T>
{
protected static List<NotificaitonSettings<T>> settings = new List<NotificaitonSettings<T>>();
static NotificationServiceFactory()
{
settings.Add(new NotificaitonSettings<T>
{
Predicate = m => !String.IsNullOrEmpty(m.Email),
Service = new NotificationService(new EmailNotification(), new EmailFormatter())
});
settings.Add(new NotificaitonSettings<T>
{
Predicate = m => !String.IsNullOrEmpty(m.Fax),
Service = new NotificationService(new FaxNotification(), new FaxFormatter())
});
}
public NotificationService Create(T model)
{
return settings.FirstOrDefault(s => s.Predicate(model)).Service;
}
}
此实现使用静态列表配置工厂,如果它支持此类操作,则可以使用IoC容器。