我正在尝试在C#Web API中创建一个休息服务。
目前我没有考虑任何数据库决策,因此我添加了一个模拟类库。
我正在创建模型接口并在模拟类库中实现模型。
public interface IUser
{
int userId { get; set; }
string firstName { get; set; }
string lastName { get; set; }
string email { get; set; }
List<IUser> getAllUsers();
IUser getUser(int ID);
bool updateUser(IUser user);
bool deleteUser(int ID);
}
并在模拟类库中实现它
public class User : IUser
{
public string email { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public int userId { get; set; }
public bool deleteUser(int ID)
{
throw new NotImplementedException();
}
public List<IUser> getAllUsers()
{
throw new NotImplementedException();
}
public IUser getUser(int ID)
{
throw new NotImplementedException();
}
public bool updateUser(IUser user)
{
throw new NotImplementedException();
}
}
现在模拟库引用服务应用程序来实现接口。
现在我需要从服务应用程序中的控制器类调用模拟实现。
如何在不创建循环依赖的情况下执行此操作。我做了一些研究,并想出了一个解决方案,DI是最佳选择。
有人可以帮我用代码示例实现吗?
非常感谢。
答案 0 :(得分:0)
如果您不介意使用哪个IoC容器,我会推荐Ninject。
您需要通过Nuget安装下一个软件包:
然后在Ninject配置文件NinjectWebCommon.cs中,在RegisterServices()方法的末尾添加以下代码:
kernel.Bind<IUser>().To<User>();
现在只需将IUser作为参数添加到控制器类中,Ninject将自动注入它。
public class MyController : Controller
{
private IUser _user;
// Ninject will automatically inject a User instance here
// on controller creation
public MyController(IUser user)
{
_user = user;
}
}
使用Ninject有不同的方法,因此您可以搜索更符合您需求的其他方法。
答案 1 :(得分:0)
&#34;现在我需要从服务应用程序中的控制器类调用模拟实现。&#34;
这听起来不对。我觉得你这里有设计问题;为什么需要从服务应用程序中引用IUser
的模拟实现?
要记住的一件事是客户端拥有接口,因此IUser
接口根本不属于Mock类库;理想情况下,它应该在一个完全独立的程序集中定义,这样你的模拟类库和你的服务类库都可以引用它(并在需要时提供它们自己的实现)。
这是Dependency Inversion Principle虽然我同意某种DI库可以帮助您管理这种反转控制的实现,但我不相信它会对您有所帮助从长远来看。您可能仍会在容器本身遇到相同的循环引用问题。
现在我认为在您查看使用任何DI库之前,我首先需要考虑使用Stairway Pattern来正确反转您的依赖关系
答案 2 :(得分:0)
现在模拟库引用服务应用程序来实现接口。
这是您的问题的根源。我建议将数据访问层的接口移到单独的项目中。然后,您可以使用模拟/内存实现创建项目,稍后再添加具有实际实现的项目。
另一件事是您的IUser
是DTO(数据传输对象)的合同,但它包含DAO(数据访问对象)方法。通常,您可能希望将这些问题与存储库模式分开。
public interface IUserRepository
{
IEnumerable<IUser> GetAllUsers();
IUser GetUser(int id);
...
}
此存储库是您注入API控制器的内容。