我发现我的构造函数开始看起来像这样:
public MyClass(Container con, SomeClass1 obj1, SomeClass2, obj2.... )
Run Code Online (Sandbox Code Playgroud)
随着参数列表不断增加.由于"容器"是我的依赖注入容器,为什么我不能这样做:
public MyClass(Container con)
Run Code Online (Sandbox Code Playgroud)
每个班级?有什么缺点?如果我这样做,感觉我正在使用一个美化的静电.请分享您对IoC和依赖注入疯狂的看法.
c# java dependency-injection ioc-container inversion-of-control
我目前正在权衡DI和SL之间的优缺点.但是,我发现自己处于以下问题22中,这意味着我应该只使用SL作为一切,并且只在每个类中注入一个IoC容器.
DI Catch 22:
一些依赖项,如Log4Net,根本不适合DI.我称之为元依赖关系并认为它们对调用代码应该是不透明的.我的理由是,如果一个简单的类'D'最初是在没有记录的情况下实现的,然后增长到需要记录,那么依赖类'A','B'和'C'现在必须以某种方式获得这种依赖并将其从'A'到'D'(假设'A'组成'B','B'组成'C',依此类推).我们现在已经进行了重要的代码更改,因为我们需要登录一个类.
因此,我们需要一种不透明的机制来获取元依赖性.我想到了两个:Singleton和SL.前者具有已知的局限性,主要是关于刚性范围的能力:最好的是Singleton将使用存储在应用程序范围内的抽象工厂(即在静态变量中).这允许一些灵活性,但并不完美.
更好的解决方案是将IoC容器注入此类,然后使用该类中的SL从容器中解析这些元依赖关系.
因此,捕获22:因为类现在正在注入IoC容器,那么为什么不使用它来解析所有其他依赖项呢?
我非常感谢你的想法:)
c# singleton dependency-injection dependency-management service-locator
如何在ninject 2.0中使用此功能?
MyType obj = kernel.Get<MyType>(With.Parameters.ConstructorArgument("foo","bar"));
Run Code Online (Sandbox Code Playgroud)
"With"不存在:(
对于DI和ninject来说,我是一个新手,我正在努力解决实际注入何时发生以及如何开始绑定的问题.
我已经在我的Web应用程序中使用它并且它在那里工作正常,但现在我想在类库中使用注入.
说我有这样一个类:
public class TestClass
{
[Inject]
public IRoleRepository RoleRepository { get; set; }
[Inject]
public ISiteRepository SiteRepository { get; set; }
[Inject]
public IUserRepository UserRepository { get; set; }
private readonly string _fileName;
public TestClass(string fileName)
{
_fileName = fileName;
}
public void ImportData()
{
var user = UserRepository.GetByUserName("myname");
var role = RoleRepository.GetByRoleName("myname");
var site = SiteRepository.GetByID(15);
// Use file etc
}
}
Run Code Online (Sandbox Code Playgroud)
我想在这里使用属性注入,因为我需要在构造函数中传入一个文件名.我是否正确说,如果我需要传入一个构造函数参数,我不能使用构造函数注入?如果我可以使用带有附加参数的构造函数注入,我该如何传递这些参数?
我有一个由Test类使用的控制台应用程序,如下所示:
class Program
{
static void Main(string[] args)
{
// NinjectRepositoryModule Binds my IRoleRepository …Run Code Online (Sandbox Code Playgroud) 假设我正在为我的应用程序定义一个浏览器实现类:
class InternetExplorerBrowser : IBrowser {
private readonly string executablePath = @"C:\Program Files\...\...\ie.exe";
...code that uses executablePath
}
Run Code Online (Sandbox Code Playgroud)
乍一看这可能看起来是个好主意,因为executablePath数据接近将使用它的代码.
当我尝试在另一台具有外语操作系统的计算机上运行相同的应用程序时executablePath会出现问题:将具有不同的值.
我可以通过AppSettings单例类(或其等价物)来解决这个问题,但是没有人知道我的类实际上依赖于这个AppSettings类(它违背了DI ideias).它也可能给单元测试带来困难.
我可以executablePath通过构造函数传入来解决这两个问题:
class InternetExplorerBrowser : IBrowser {
private readonly string executablePath;
public InternetExplorerBrowser(string executablePath) {
this.executablePath = executablePath;
}
}
Run Code Online (Sandbox Code Playgroud)
但这会引起我的问题Composition Root(启动方法将执行所有需要的类连接),因为那个方法必须知道如何连接并且必须知道所有这些小设置数据:
class CompositionRoot {
public void Run() {
ClassA classA = new ClassA();
string ieSetting1 = "C:\asdapo\poka\poskdaposka.exe";
string ieSetting2 = "IE_SETTING_ABC";
string ieSetting3 = "lol.bmp";
ClassB classB = new ClassB(ieSetting1); …Run Code Online (Sandbox Code Playgroud) 我有这样的事情:
class Root
{
public Root(IDependency dep)
{}
}
class Dependency:IDependency
{
public Dependency(int val)
{}
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用ninject获取对Root的引用.所以我这样配置它
var module = new InlineModule(mod => mod.Bind<IDependency>().To<Dependency>());
var kernel = new StandardKernel(module);
Run Code Online (Sandbox Code Playgroud)
我想向Dependency注入一些'val'值,这个值仅在从ninject获取Root引用时才知道.
我想做的是这样的事情:
Kernel.Instance.Get<Root>(With.Parameters.ConstructorArgument("val", 12));
Run Code Online (Sandbox Code Playgroud)
使用ninject 1.0是否可以这样?
我有这个界面:
public interface IUserProfileService
{
// stuff
}
Run Code Online (Sandbox Code Playgroud)
实施者:
public class UserProfileService : IUserProfileService
{
private readonly string m_userName;
public UserProfileService(string userName)
{
m_userName = userName;
}
}
Run Code Online (Sandbox Code Playgroud)
我需要将这个注入到这样的控制器中:
public class ProfilesController : BaseController
{
private readonly IUserProfileService m_profileService;
public ProfilesController(IUserProfileService profileService)
{
m_profileService = profileService;
}
}
Run Code Online (Sandbox Code Playgroud)
我不知道如何将此接口及其实现注册到Ninject容器中,以便在Ninject进入此服务的实例时传入userName参数.
我有什么想法可以达到这个目的吗?
这是手头的问题:
在调用我CustomerController的时候URL,我得到以下异常:
ExceptionMessage:
尝试创建"CustomerController"类型的控制器时发生错误.确保控制器具有无参数的公共构造函数.
我使用以下网址:
请注意:
/api/Customer/在我将逻辑重构为业务类并实现依赖注入之前,调用正在进行.
我的研究表明,我没有正确地注册我的界面和课程Ninject,但不确定我错过了哪一步.
研究链接:
这是我的问题导致此异常的原因是什么?我正在注册我的接口/类
Ninject,但它似乎没有正确识别映射.有什么想法吗?
客户控制员
public class CustomerController : ApiController
{
private readonly ICustomerBusiness _customerBusiness;
public CustomerController(ICustomerBusiness customerBusiness)
{
_customerBusiness = customerBusiness;
}
// GET api/Customer
[HttpGet]
public IEnumerable<Customer> GetCustomers()
{
return _customerBusiness.GetCustomers();
}
// GET api/Customer/Id
[HttpGet]
public IEnumerable<Customer> GetCustomersById(int customerId)
{
return _customerBusiness.GetCustomerById(customerId);
}
}
Run Code Online (Sandbox Code Playgroud)
客户业务
public class CustomerBusiness : ICustomerBusiness
{
private readonly DatabaseContext …Run Code Online (Sandbox Code Playgroud) 我有一个 ASP.MVC 项目,其中使用 ninject 作为 IOC 容器。我已将绑定添加为基础结构文件夹中的单独类,如下所示:
public class NinjectControllerFactory : DefaultControllerFactory{
private readonly IKernel _ninjectKernal;
public NinjectControllerFactory()
{
_ninjectKernal = new StandardKernel();
PSCCheckContext m = _ninjectKernal.Get<PSCCheckContext>(new IParameter[]
{ new ConstructorArgument("appNamekey", "Name of Staff Application"),
new ConstructorArgument("serverLocationNameKey", "Location of Application Server") });
AddBindings();
}
Run Code Online (Sandbox Code Playgroud)
所以您可以看到我正在尝试在 PSCCheckContext 的构造函数中设置 web.config 中的两个参数。这是另一个处理数据库访问的 C# 应用程序。AddBindings() 类只是将接口类映射到您所期望的具体实现:
private void AddBindings()
{
...
_ninjectKernal.Bind<IPSCCheckContext>().To<PSCCheckContext>();
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是 PSCCheckContext 类中有 2 个构造函数,其中第二个构造函数采用不同的参数:
public class PSCCheckContext : IPSCCheckContext
{
public PSCCheckContext(string appNamekey, string serverLocationNameKey);
public PSCCheckContext(string imgNamekey, string imgFlagKey, …Run Code Online (Sandbox Code Playgroud)