我正在使用TDD在C#中开发一个简单的服务定位器。
目前,我已经创建了一个TryAddService
方法,如下所示:
public bool TryAddService(Type type, object service)
{
if (service == null)
{
return false;
}
if (this.services.ContainsKey(type))
{
return false;
}
if (!type.IsAssignableFrom(service.GetType()))
{
return false;
}
this.services.Add(type, service);
return true;
}
我的问题是,在所有这些情况下我应该归还假吗?或者我应该抛出异常?
我在这种情况下的客户将是其他开发人员。
非正式地同意,无论何时使用TryXXXX模式,您的方法必须始终成功,但返回实际成功结果为布尔值。如果你想抛出和Exception,那么只需从你的方法名称中删除“try”一词。
在顶部,如果你遵循TryXXXX模式,我建议你添加一个try-catch块,以确保你的方法总是成功:
public bool TryAddService(Type type, object service)
{
if (service == null)
{
return false;
}
if (this.services.ContainsKey(type))
{
return false;
}
if (!type.IsAssignableFrom(service.GetType()))
{
return false;
}
try
{
this.services.Add(type, service);
}
catch
{
return false;
}
return true;
}
我使用这个场景:我有一个类,所有服务都返回这个名为的类(例如MyReturn)
public sealed class MyReturn<TEntity> : IDisposable
{
public string Message { get; set; }
public TEntity Entity { get; set; }
public string SysException { get; set; }
// and etc...
public void Dispose() {}
}
现在您的服务:
public MyReturn <bool> TryAddService(Type type, object service)
{
if (service == null)
return new MyReturn <bool> {Message = "Your messgage"};
//and etc...
return new MyReturn <bool>();
}
在你的表单中你检查消息,如果为空或空,你没有错误....你可以自定义它...
我在这种情况下的客户将是其他开发人员。
您是否期望您班级的消费者会有条件地注册类型?
if (TryAddService(typeof(IService), new Service1()))
{
// Added successfully - what to do next
}
else
{
// What here? Try another service?
}
或者开发人员只需注册他们需要的实现,并依赖于TryAddService
在应用程序启动期间抛出异常的事实。
TryAddService(typeof(IService), new Service1());
作为开发人员,如果我做错了,我希望尽可能得到最快的反馈。在应用程序启动期间抛出异常(通常是服务注册完成)将是最快的反馈。除非您使用带有约束的泛型,否则它将在编译期间提供反馈。
如果开发人员没有注册失败的逻辑,则不返回任何内容,而是使用描述性消息抛出自定义异常
public void TryAddService(Type type, object service)
{
if (service == null)
{
throw new RegisterServiceException($"Can not register null for type '{type.FullName}'");
}
if (this.services.ContainsKey(type))
{
throw new RegisterServiceException($"Service for type '{type.FullName}' already registerd.");
}
if (!type.IsAssignableFrom(service.GetType()))
{
throw new RegisterServiceException($"Type '{type.FullName}' should be assignable from service of type '{service.GetType().FullName}'");
}
this.services.Add(type, service);
}