我有一个代表聊天室并且依赖于记录器的类。它与具有横切关注点的系统级记录器不同,而是与特定聊天室相关联的记录器。它将该聊天室中的所有活动记录到其唯一的日志文件中。创建聊天室时,我想打开日志文件,当它被销毁时,我想关闭日志文件。
这是我正在使用的相关代码。
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);
}
它在这样的应用程序中使用:
var room = ChatManager.Get(chatroomName);
romm.DoStuff();
room.Logger.LogPacket(receivedPacket);
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);
}
}
由于某种原因,这似乎是错误的。如果没有域名知道我正在使用什么DI容器,这似乎更清晰。
如果我的应用程序在运行过程中没有求助于某种服务定位器设计,我怎么能得到类Chatroom
的新实例?我是否在思考它?绕过Unity是不是一件大事?欢迎任何想法!
答案 0 :(得分:4)
IFactory<T>
接口,如下所示:
public IFactory<T>
{
T Get();
}
然后使用 知道的类实现接口并使用IUnityContainer
。设置绑定,以便IFactory<>
请求将创建此工厂类的实例。这样,您可以将IFactory<Logger>
接口注入ChatManager
,并在需要记录器实例时随时调用.Get()
。
答案 1 :(得分:1)
一般来说,我也认为你应该避免绕过容器。