在使用依赖注入时,我一直认为我的接口和具体类之间有一对一的关系.当我需要向接口添加方法时,我最终会破坏实现该接口的所有类.
这是一个简单的例子,但我们假设我需要在ILogger
我的一个类中注入一个.
public interface ILogger
{
void Info(string message);
}
public class Logger : ILogger
{
public void Info(string message) { }
}
Run Code Online (Sandbox Code Playgroud)
像这样的一对一关系感觉就像代码味道.由于我只有一个实现,如果我创建一个类并将该Info
方法标记为虚拟以在我的测试中覆盖而不是仅为一个类创建一个接口,是否有任何潜在的问题?
public class Logger
{
public virtual void Info(string message)
{
// Log to file
}
}
Run Code Online (Sandbox Code Playgroud)
如果我需要另一个实现,我可以覆盖该Info
方法:
public class SqlLogger : Logger
{
public override void Info(string message)
{
// Log to SQL
}
}
Run Code Online (Sandbox Code Playgroud)
如果这些类中的每一个都具有可以创建漏洞抽象的特定属性或方法,我可以提取出一个基类:
public class Logger
{
public virtual void Info(string message)
{
throw new NotImplementedException();
} …
Run Code Online (Sandbox Code Playgroud) public class Demo
{
private List<string> _items;
private List<string> Items
{
get
{
if (_items == null)
_items = ExpensiveOperation();
return _items;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Demo
该类中的其他方法将可以访问该_items
字段.由于我使用属性来延迟加载项目,我不希望其他开发人员错误地尝试使用该_items
字段.
我知道我可以使用的是ObsoleteAttribute,但是这个领域在技术上并不过时.
有没有更好的方法将会员标记为"不使用"?
当我在调试模式下运行以下代码时,它将成功完成并退出.但是,如果我在发布模式下运行以下代码,它将陷入无限循环而永远不会完成.
static void Main(string[] args)
{
bool stop = false;
new Thread(() =>
{
Thread.Sleep(1000);
stop = true;
Console.WriteLine("Set \"stop\" to true.");
}).Start();
Console.WriteLine("Entering loop.");
while (!stop)
{
}
Console.WriteLine("Done.");
}
Run Code Online (Sandbox Code Playgroud)
哪种优化导致它陷入无限循环?
我试图了解何时应该使用容器而不是手动注入依赖项.如果我有一个使用1-2接口的应用程序,并且每个接口只有1-2个具体实现,我会倾向于自己处理.
如果我有一个使用2-3个接口的小应用程序,每个接口有2-3个具体实现,我应该使用一个完整的容器吗?像这样简单的东西就足够了吗?
基本上我试图理解何时适合手动处理这些依赖关系,什么时候(或者如果)我应该使用像上面那样简单的东西,何时使用像Ninject,Windsor等的IOC容器....它可能不会适合在这样的事情上加上一个数字,但我怎么能告诉它是时候使用IOC容器了?
我正在使用FirstChanceException事件来记录有关任何抛出异常的详细信息.
static void Main(string[] args)
{
AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) =>
{
Console.WriteLine("Inside first chance exception.");
};
throw new Exception("Exception thrown in main.");
}
Run Code Online (Sandbox Code Playgroud)
这按预期工作.但是如果在事件处理程序中抛出异常,则会发生堆栈溢出,因为事件将以递归方式引发.
static void Main(string[] args)
{
AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) =>
{
throw new Exception("Stackoverflow");
};
throw new Exception("Exception thrown in main.");
}
Run Code Online (Sandbox Code Playgroud)
如何处理事件处理程序中发生的异常?
编辑:
有一些答案表明我将代码包装在try/catch块中的事件处理程序中,但这不起作用,因为在处理异常之前引发了事件.
static void Main(string[] args)
{
AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) =>
{
try
{
throw new Exception("Stackoverflow");
}
catch
{
}
};
throw new Exception("Exception thrown in main.");
}
Run Code Online (Sandbox Code Playgroud) 我有一个WinForm项目,其中包含一个名为MainUI的表单.您可以看到自动生成的分部类显示为下的节点MainUI.cs
.有没有办法"移动"我自己创建的部分类MainUI.Other.cs
,MainUI.cs
以便它将显示为另一个节点?
我有一个执行java应用程序的批处理文件.我正在尝试修改它,以便每当发生异常时,它都会将STDERR写入文件.
它看起来像这样:
start java something.jar method %1 %2 2>> log.txt
Run Code Online (Sandbox Code Playgroud)
有没有办法可以将参数%1和%2写入log.txt文件?每次调用此批处理文件时,我都不希望将其写入日志文件,仅在发生异常时.
我试图找到一种方法将STDERR重定向到一个变量,但我无法弄明白.理想情况下,我希望日志文件看起来像:
Batch file called with parameters:
- "first arg"
- "second arg"
Exception:
java.io.exception etc...
------------------------------------
Batch file called with parameters:
- "first arg"
- "second arg"
Exception:
java.io.exception etc...
Run Code Online (Sandbox Code Playgroud) public class Demo
{
public void When(Func<Person, bool> condition)
{
if (!condition)
{
Log.Info("Condition not met.");
return;
}
// Do something
}
}
Run Code Online (Sandbox Code Playgroud)
在When
方法中,我想记录谓词或Func<bool>
返回false.但是,只记录"未满足的条件"并没有给我太多信息.如果我这样调用方法:
demo.When(x => x.Name == "John");
Run Code Online (Sandbox Code Playgroud)
有没有办法将该表达式转换为可读/有意义的字符串以进行日志记录?
在格式化样式下的ReSharper选项菜单中,它显示格式化后代码的外观.这些存放在哪里?
我打算将我的样式设置发布到共享位置,以便我的团队中的其他开发人员可以导入设置.我还希望有一个文档,人们可以在导入设置之前查看,以查看格式化后代码的样子.
是否有某些显示默认值的在线文档?或者更确切地说有一种方法可以导出(或解析这些片段是否存储在磁盘上的某个位置),以便我可以将其格式化以便显示而无需单独检查每个设置并复制/粘贴?
如何组织IoC容器的配置?我知道按代码注册应该放在应用程序的最高级别,但是如果应用程序有数百个需要注册的依赖项呢?与XML配置相同.我知道您可以将XML配置拆分为多个文件,但如果有人不得不挖掘多个XML文件,那么这似乎会成为一种维护麻烦.
是否有组织依赖注册的最佳实践?从我见过的所有视频和教程中,演示中使用的代码非常简单,可以放在一个位置.我还没有遇到过使用大量依赖项的示例应用程序.