Rad*_*ive 6 c# oop design-patterns
因为我对OOP/C#相对较新,我不知道解决这个问题的正确模式:
我必须为不同的IO提供商构建一个插件架构.主机从配置中读取所需的提供程序名称/类型,然后它应该是提供程序实例化和参数化.
所以我基本上有这个接口:
public interface IoProvider //(Base interface, all Providers implements this)
{
void Initialize();
void Execute();
}
public interface IFileProvider: IoProvider
{
string PropertyA { get; set; }
}
public interface ISmtpProvider : IoProvider
{
string PropertyB { get; set; }
string PropertyC { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
如您所见,派生的专用IO提供程序具有基本接口所没有的不同附加参数属性.为了避免if/then/else或switch语句我的想法是使用工厂模式.
但如果我理解正确,它不能解决我的if/then/else问题,因为在客户端我必须检查派生类型以提供正确的参数.
因此,主机上的程序流将是这样的:主机读取配置,获取所需的名称/类型提供者主机调用工厂并获取提供者
但是如何避免这种情况 - 有没有if/then/else解决这个问题的模式?
If (provider == typeOf(IFileProvider))
PropertyA = value
else if (provider == typeOf(ISmtpProvider))
PropertyB = value
PropertyC = value
Elseif …
Run Code Online (Sandbox Code Playgroud)
Ser*_*kiy 14
您可以switch
使用多态替换语句.只允许每个提供程序从config配置自己.这是一个最佳选择,因为每个提供程序都知道要查找的值:
provider.Configure();
Run Code Online (Sandbox Code Playgroud)
此方法应存在于基接口中:
public interface IoProvider
{
void Initialize();
void Execute();
void Configure();
}
Run Code Online (Sandbox Code Playgroud)
每个提供商都实现它:
public interface ISmtpProvider : IoProvider
{
string PropertyB { get; set; }
string PropertyC { get; set; }
public void Configure()
{
PropertyB = ConfigurationManager.AppSettins["B"];
PropertyB = ConfigurationManager.AppSettins["C"];
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法的主要好处是,只有一个地方可以更改,当新的提供程序添加到您的应用程序时 - 只需添加新的提供程序类,它知道如何自行配置.您也不需要更改主机实现.并且您的主机将满足OCP原则 - 打开扩展(您可以添加新的提供程序),但关闭以进行修改(您不需要在添加新提供程序时修改现有代码).
您还可以将一些配置对象传递Configure(IConfiguration config)
给此方法(它将使您的代码可测试,而不依赖于静态ConfigurationManager
).