Oni*_*mus 6 c# dependency-injection ioc-container unity-container
我有一个代表聊天室的类,并且依赖于记录器.它与具有横切关注点的系统级记录器不同,而是与特定聊天室相关联的记录器.它将该聊天室中的所有活动记录到其唯一的日志文件中.创建聊天室时,我想打开日志文件,当它被销毁时,我想关闭日志文件.
这是我正在使用的相关代码.
public interface IChatroomLogger
{
void Log(ServerPacket packet);
void Open();
void Close();
}
public class ChatroomLogger : IChatroomLogger
{
// chatroom name will be used as a file name
public ChatroomLogger(string chatroomName) { ... }
public void Log(ServerPacket packet) { ... }
}
public class Chatroom
{
public Chatroom(string name, IChatroomLogger logger)
{
this.name = name;
this.logger = logger;
this.logger.Open();
}
public IChatromLogger Logger { get { return this.logger; } }
}
public interface IChatManager
{
Chatroom Get(chatroomName);
}
Run Code Online (Sandbox Code Playgroud)
它在这样的应用程序中使用:
var room = ChatManager.Get(chatroomName);
romm.DoStuff();
room.Logger.LogPacket(receivedPacket);
Run Code Online (Sandbox Code Playgroud)
这ChatManager是一个包含所有聊天室引用的类,负责创建和删除它们.我还没有写它,但这是我编写的接口.
我如何ChatManager创建新的实例Chatroom并仍然使用依赖注入?
我正在使用Unity来完成我所有其他的DI工作.到目前为止它的效果很好.但我不知道如何解决这个难题.
当我的具体实现ChatManager创建新的聊天室时,它必须通过一个IChatroomLogger.它不知道如何构建......但Unity确实如此.但后来我必须IUnityContainer进入ChatManager.
public class ChatManager : IChatManager
{
public ChatManager(IUnityContainer container)
{
this.container = container;
}
public Chat Get(string chatroomName)
{
// get logger from Unity somehow. Not sure how I'd
// pass chatroomName to the concrete instance
var logger = ...
return new Chatroom(chatroomName, logger);
}
}
Run Code Online (Sandbox Code Playgroud)
出于某种原因,这似乎是错误的.如果没有域名知道我正在使用什么DI容器,这似乎更清晰.
如果Chatroom我的应用程序在运行过程中没有求助于某种服务定位器设计,我怎么能得到新的类实例?我是否在思考它?绕过Unity是不是一件大事?欢迎任何想法!
你说得对。像这样使用IUnityContainer就不再使用依赖注入了。相反,它使用“服务定位器”模式。在这种情况下,我通常会创建一个IFactory<T>接口,如下所示:
public IFactory<T>
{
T Get();
}
Run Code Online (Sandbox Code Playgroud)
然后使用一个了解并使用IUnityContainer. 设置您的绑定,以便IFactory<>请求将创建此工厂类的实例。这样,您可以将IFactory<Logger>接口注入到您的 中ChatManager,并.Get()在需要记录器实例时随时调用。