.NET Core 中的依赖注入
Dependency injection in .NET Core
我正在尝试在控制器中创建 class 的实例。但是,我做不到。
控制器代码:
[HttpPost]
[Route("connection")]
public async Task<IActionResult> DoSomething(string firstName, string lastName)
{
return new OkObjectResult(new MyClass().ShowData(firstName, lastName));
}
Class代码:
public interface ISomeInterface
{
void SomeMethod();
}
public class MyClass
{
private readonly ISomeInterface _someInterface;
public MyClass(ISomeInterface someInterface)
{
_someInterface = someInterface;
}
public Task<bool> ShowData(string firstName, string lastName)
{
// some logic
if (firstName == "Ram")
{
ClassOne obj1 = new ClassOne();
obj1.DoPlus();
} else if (firstName == "Sam")
{
ClassTwo obj1 = new ClassTwo();
obj1.DoPlus();
}
return Task.FromResult(true);
}
}
另一个界面
public interface IClassOneTwo
{
void DoPlus();
}
public class ClassOne : IClassOneTwo
{
public void DoPlus()
{ }
}
public class ClassTwo : IClassOneTwo
{
public void DoPlus()
{ }
}
如何将 ISomeInterface
注入控制器?另外,如何分离 ClassOne 和 ClassTwo 的实例?我想注册 IClassOneTwo 接口并基于 IF/ELSE 条件,我想获得 ClassOne 或 ClassTwo.
的实例
为了完整起见,您应该在接口后面抽象 MyClass
。
例如:
public interface IMyClass
{
Task<bool> ShowData(string firstName, string lastName);
}
并让 MyClass
实施它:
public class MyClass : IMyClass
{
private readonly ISomeInterface _someInterface;
public MyClass(ISomeInterface someInterface)
{
_someInterface = someInterface;
}
public Task<bool> ShowData(string firstName, string lastName)
{
// some logic
return Task.FromResult(true);
}
}
那么在你的Startup.cs
class,ConfigureServices
方法中,你应该注册一下:
services.AddTransient<IMyClass, MyClass>();
您还应该注册 ISomeInterface
:
services.AddTransient<ISomeInterface, SomeOtherClass>();
然后,在你的控制器中,你应该通过构造函数注入你想要的服务:
public sealed class MyController : ControllerBase
private readonly IMyClass _myClass;
public MyController(IMyClass myClass)
{
_myClass = myClass;
}
[HttpPost, Route("connection")]
public async Task<IActionResult> DoSomething(
[FromQuery]string firstName, [FromQuery]string lastName)
{
return Ok(await _myClass.ShowData(firstName, lastName));
}
}
编辑添加...
OP 询问如何使 MyClass
或多或少成为可以使用 ISomeInterface
执行操作的实用程序。所以,你还是想注册ISomeInterface
到管道:
services.AddTransient<ISomeInterface, SomeOtherClass>();
您可以 MyClass
切换回原来的状态。
如上所示将 ISomeInterface
注入您的控制器,然后将其传递给 MyClass
:
public sealed class MyController : ControllerBase
private readonly ISomeInterface _someOtherClass;
public MyController(ISomeInterface someOtherClass)
{
_someOtherClass = someOtherClass;
}
[HttpPost, Route("connection")]
public async Task<IActionResult> DoSomething(
[FromQuery]string firstName, [FromQuery]string lastName)
{
return Ok(await new MyClass(_someOtherClass)
.ShowData(firstName, lastName));
}
}
编辑添加(再次)...
所以我认为我们已经弄清了 OP 想要什么。他们想注入两个共享相同接口的服务。有很多方法可以做到这一点。我会坚持使用我过去使用过的那个。
首先,定义一个委托:
public delegate IClassOneTwo MyServiceResolver(string key);
然后在你的Startup.cs
中,在ConfigureServices
方法中,注册:
services.AddTransient<ClassOne>();
services.AddTransient<ClassTwo>();
请记住,我们在注册时不使用界面。这很重要。
现在我们创建另一个服务,可以解决您想要的服务:
services.AddTransient<MyServiceResolver>(serviceProvider => key =>
{
switch (key)
{
case "Ram":
return serviceProvider.GetService<ClassOne>();
case "Sam":
return serviceProvider.GetService<ClassTwo>();
default:
return null; // or throw an exception
}
});
然后,在您决定注入的任何服务中(为简单起见,我将使用控制器):
public sealed class MyController : ControllerBase
private readonly MyServiceResolver _serviceResolver;
public MyController(MyServiceResolver serviceResolver)
{
_serviceResolver = serviceResolver;
}
[HttpPost, Route("connection")]
public IActionResult DoSomething(
[FromQuery]string firstName, [FromQuery]string lastName)
{
_serviceResolver(firstName).DoPlus();
return Ok();
}
}
现在,您的服务将在运行时解析。
我正在尝试在控制器中创建 class 的实例。但是,我做不到。
控制器代码:
[HttpPost]
[Route("connection")]
public async Task<IActionResult> DoSomething(string firstName, string lastName)
{
return new OkObjectResult(new MyClass().ShowData(firstName, lastName));
}
Class代码:
public interface ISomeInterface
{
void SomeMethod();
}
public class MyClass
{
private readonly ISomeInterface _someInterface;
public MyClass(ISomeInterface someInterface)
{
_someInterface = someInterface;
}
public Task<bool> ShowData(string firstName, string lastName)
{
// some logic
if (firstName == "Ram")
{
ClassOne obj1 = new ClassOne();
obj1.DoPlus();
} else if (firstName == "Sam")
{
ClassTwo obj1 = new ClassTwo();
obj1.DoPlus();
}
return Task.FromResult(true);
}
}
另一个界面
public interface IClassOneTwo
{
void DoPlus();
}
public class ClassOne : IClassOneTwo
{
public void DoPlus()
{ }
}
public class ClassTwo : IClassOneTwo
{
public void DoPlus()
{ }
}
如何将 ISomeInterface
注入控制器?另外,如何分离 ClassOne 和 ClassTwo 的实例?我想注册 IClassOneTwo 接口并基于 IF/ELSE 条件,我想获得 ClassOne 或 ClassTwo.
为了完整起见,您应该在接口后面抽象 MyClass
。
例如:
public interface IMyClass
{
Task<bool> ShowData(string firstName, string lastName);
}
并让 MyClass
实施它:
public class MyClass : IMyClass
{
private readonly ISomeInterface _someInterface;
public MyClass(ISomeInterface someInterface)
{
_someInterface = someInterface;
}
public Task<bool> ShowData(string firstName, string lastName)
{
// some logic
return Task.FromResult(true);
}
}
那么在你的Startup.cs
class,ConfigureServices
方法中,你应该注册一下:
services.AddTransient<IMyClass, MyClass>();
您还应该注册 ISomeInterface
:
services.AddTransient<ISomeInterface, SomeOtherClass>();
然后,在你的控制器中,你应该通过构造函数注入你想要的服务:
public sealed class MyController : ControllerBase
private readonly IMyClass _myClass;
public MyController(IMyClass myClass)
{
_myClass = myClass;
}
[HttpPost, Route("connection")]
public async Task<IActionResult> DoSomething(
[FromQuery]string firstName, [FromQuery]string lastName)
{
return Ok(await _myClass.ShowData(firstName, lastName));
}
}
编辑添加...
OP 询问如何使 MyClass
或多或少成为可以使用 ISomeInterface
执行操作的实用程序。所以,你还是想注册ISomeInterface
到管道:
services.AddTransient<ISomeInterface, SomeOtherClass>();
您可以 MyClass
切换回原来的状态。
如上所示将 ISomeInterface
注入您的控制器,然后将其传递给 MyClass
:
public sealed class MyController : ControllerBase
private readonly ISomeInterface _someOtherClass;
public MyController(ISomeInterface someOtherClass)
{
_someOtherClass = someOtherClass;
}
[HttpPost, Route("connection")]
public async Task<IActionResult> DoSomething(
[FromQuery]string firstName, [FromQuery]string lastName)
{
return Ok(await new MyClass(_someOtherClass)
.ShowData(firstName, lastName));
}
}
编辑添加(再次)...
所以我认为我们已经弄清了 OP 想要什么。他们想注入两个共享相同接口的服务。有很多方法可以做到这一点。我会坚持使用我过去使用过的那个。
首先,定义一个委托:
public delegate IClassOneTwo MyServiceResolver(string key);
然后在你的Startup.cs
中,在ConfigureServices
方法中,注册:
services.AddTransient<ClassOne>();
services.AddTransient<ClassTwo>();
请记住,我们在注册时不使用界面。这很重要。
现在我们创建另一个服务,可以解决您想要的服务:
services.AddTransient<MyServiceResolver>(serviceProvider => key =>
{
switch (key)
{
case "Ram":
return serviceProvider.GetService<ClassOne>();
case "Sam":
return serviceProvider.GetService<ClassTwo>();
default:
return null; // or throw an exception
}
});
然后,在您决定注入的任何服务中(为简单起见,我将使用控制器):
public sealed class MyController : ControllerBase
private readonly MyServiceResolver _serviceResolver;
public MyController(MyServiceResolver serviceResolver)
{
_serviceResolver = serviceResolver;
}
[HttpPost, Route("connection")]
public IActionResult DoSomething(
[FromQuery]string firstName, [FromQuery]string lastName)
{
_serviceResolver(firstName).DoPlus();
return Ok();
}
}
现在,您的服务将在运行时解析。