我的域层中有一个IClientConnection
接口,负责连接到IRC服务器。我想隐藏与服务层后面的服务器的通信。
我创建了几个服务接口。 IIrcConnectionService
提供了两种方法,ConnectToServer
和Disconnect
。它处理与IClientConnection
实现的对话。第二个服务接口是IChannelService
,提供了两种方法,JoinChannel
和PartChannel
。
public class IrcConnectionService : IIrcConnectionService
{
/// <summary>
/// The client connection
/// </summary>
private IClientConnection clientConnection;
/// <summary>
/// The connected completed callback
/// </summary>
private Action connectedCompletedCallback;
/// <summary>
/// Initializes a new instance of the <see cref="IrcConnectionService"/> class.
/// </summary>
/// <param name="clientConnection">The client connection.</param>
public IrcConnectionService(IClientConnection clientConnection)
{
this.clientConnection = clientConnection;
}
/// <summary>
/// Connects to server.
/// </summary>
/// <param name="serverInfo">The server information.</param>
/// <param name="userInfo">The user information.</param>
/// <returns>Returns an awaitable Task</returns>
public Task ConnectToServer(ServerConnectionInfo serverInfo, UserInformation userInfo, Action connectedCompletedCallback = null)
{
if (connectedCompletedCallback != null)
{
this.connectedCompletedCallback = connectedCompletedCallback;
this.clientConnection.Connected += this.OnClientConnected;
}
IrcConnectionService.CacheConnection(this.clientConnection);
return this.clientConnection.Connect(serverInfo, userInfo);
}
private void OnClientConnected(object sender, EventArgs e)
{
this.connectedCompletedCallback();
}
/// <summary>
/// Disconnects from server.
/// </summary>
/// <param name="serverInfo">The server information.</param>
public void DisconnectFromServer(ServerConnectionInfo serverInfo)
{
this.clientConnection.Connected -= this.OnClientConnected;
this.clientConnection.Disconnect();
}
}
public class ChannelService : IChannelService
{
private IIrcConnectionService connectionService;
private IClientConnection connection;
public ChannelService(IIrcConnectionService connectionService)
{
this.connectionService = connectionService;
}
public Task JoinChannel(string server, string channelName, string password = "")
{
if (!this.connectionService.IsConnected)
{
throw new InvalidOperationException("You must connect to a server prior to joining a channel.");
}
if (!channelName.StartsWith("#"))
{
channelName = channelName.Insert(0, "#");
}
return this.connectionService.SendMessage($"JOIN {channelName}");
}
public Task PartChannel(string serverNaemstring channelName)
{
throw new NotImplementedException();
}
}
应用程序可以连接到多个服务器。因此依赖注入容器(Unity)不会将它们注册为单例。相反,它会在每次需要时创建一个新实例。
此处的麻烦现在变为在同一服务的多个实例中共享IClientConnection
实例,或根据需要分享不同的服务。例如,我的视图模型使用IIrcConnectionService
的实例连接到服务器,然后使用IChannelService
加入频道。当对JoinChannel
的调用发生时,该服务的空IClientConnection
因为我不知道应该采取什么路由以便为它提供由拥有的IIrcConnectionService
共享的相同引用连接。
public class ShellViewModel
{
/// <summary>
/// The irc connection service
/// </summary>
private IIrcConnectionService ircConnectionService;
/// <summary>
/// The channel service
/// </summary>
private IChannelService channelService;
/// <summary>
/// Initializes a new instance of the <see cref="ShellViewModel"/> class.
/// </summary>
/// <param name="connectionService">The connection service.</param>
public ShellViewModel(IIrcConnectionService connectionService, IChannelService channelService)
{
this.ircConnectionService = connectionService;
this.channelService = channelService;
this.InitializeCommand = DelegateCommand.FromAsyncHandler(this.Initialize);
}
/// <summary>
/// Gets the initialize command.
/// </summary>
public DelegateCommand InitializeCommand { get; private set; }
/// <summary>
/// Initializes this instance.
/// </summary>
/// <returns>Returns an awaitable Task</returns>
private async Task Initialize()
{
var serverInfo = new ServerConnectionInfo { Url = "chat.freenode.net" };
var userInfo = new UserInformation { PrimaryNickname = "DevTestUser" };
// Connect to the server
await this.ircConnectionService.ConnectToServer(
serverInfo,
userInfo,
async () => await this.channelService.JoinChannel("#ModernIrc"));
}
}
我正在考虑的一件事是构建一个内部ConnectionCache
对象。 IIrcConnectionService
实现将按服务器名称将其IClientConnection
引用推送到它。 IChannelService
将从IClientConnection
对象通过服务器名称请求ConnectionCache
。
这听起来像是有效路径吗?有没有我可以看到的模式来解决这个问题?对此有任何指导意见。