我正在尝试使用XSockets来实现服务器,我想使用DI来抽象数据库层。
这就是我所拥有的:
public class FooController : XSocketController
{
// constructor
public FooController()
{
// initialize some data here
}
//... rest of class
}
这就是我想要的(为了能够在作为服务器的控制器上使用一些DI):
public class FooController : XSocketController
{
private IBar _myBar;
// constructor
public FooController(IBar BarImplementation)
{
// ...
_myBar = BarImplementation;
}
//...
}
问题是:我实际上并没有自己创建FooController,而是在某些客户端尝试连接它时调用它。
这是启动服务器的典型用法:
_serverContainer = Composable.GetExport<IXSocketServerContainer>();
_serverContainer.StartServers();
// Write info for each server found.
foreach (var server in _serverContainer.Servers)
{
Console.WriteLine(server.ConfigurationSetting.Endpoint);
Console.WriteLine( "Allowed Connections (0 = infinite): {0}",
server.ConfigurationSetting.NumberOfAllowedConections);
}
如果我没有弄错(我可能会这样),当客户端尝试连接时,他会将自己的私有控制器作为服务器。
关于如何解决这个问题的任何想法?
答案 0 :(得分:1)
有几种方法可以做到这一点,但是(目前)没有办法在控制器上进行构造函数注入。您可以在自己定义的其他类中使用它...
这是一种做法。
/// <summary>
/// Interface with export attribute
/// </summary>
[Export(typeof(IBar))]
public interface IBar
{
void SomeMethod();
}
/// <summary>
/// Implementation of IBar
/// </summary>
public class Bar : IBar
{
public void SomeMethod()
{
}
}
/// <summary>
/// Controller with IBar property
/// </summary>
public class Foo : XSocketController
{
private IBar bar;
public Foo()
{
bar = Composable.GetExport<IBar>();
}
}
编辑: 回答评论中的问题。
GetExport<T>
期望找到一个实现该接口的实例。如果您有多个实现界面的类,则应使用
GetExports<T>
我们没有构造函数注入等的原因是大多数时候人们添加某种IService或IRepository。这将打开一个数据库连接,只要控制器存在就会打开,只要客户端连接就可以。这很糟糕:)所以当需要数据访问时,你应该使用
GetExport<IMyService>
使用它然后当你退出方法时,连接将被关闭。
您也可以使用Ninject等,但您仍然应该尽可能短时间地创建具有数据访问权限的对象。
答案 1 :(得分:1)
只是一些额外的信息。 在下一个版本(明天4.0 alpha),您将能够喜欢这个
/// <summary>
/// Interface with export attribute
/// </summary>
[Export(typeof(IBar))]
public interface IBar
{
void SomeMethod();
}
/// <summary>
/// Implementation of IBar
/// </summary>
public class Bar : IBar
{
public void SomeMethod()
{
}
}
然后使用像这样的ImportingConstrcutor ......
/// <summary>
/// Controller with IBar property
/// </summary>
public class Foo : XSocketController
{
public IBar Bar { get; set; }
public Foo(){}
[ImportingConstructor]
public Foo(IBar bar)
{
this.Bar = bar;
}
}
或者像这样使用ImportOne ......
/// <summary>
/// Controller with IBar property
/// </summary>
public class Foo : XSocketController
{
[ImportOne(typeof(IBar))]
public IBar Bar { get; set; }
}