我正在努力解决使用untiy的依赖注入问题.我已根据此链接实施https://www.asp.net/web-api/overview/advanced/dependency-injection
但得到了这个错误:
{
"Message": "An error has occurred.",
"ExceptionMessage": "An error occurred when trying to create a controller of type 'WebAPIController'. Make sure that the controller has a parameterless public constructor.",
"ExceptionType": "System.InvalidOperationException",
"StackTrace": " at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "Type 'Fairmoves.Controllers.WebAPIController' does not have a default constructor",
"ExceptionType": "System.ArgumentException",
"StackTrace": " at System.Linq.Expressions.Expression.New(Type type)\r\n at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type …Run Code Online (Sandbox Code Playgroud)asp.net-mvc dependency-injection inversion-of-control unity-container asp.net-web-api
根据MSDN,类的Resolve<T>()方法UnityContainer使用如下:
var controller = container.Resolve<ManagementController>();
Run Code Online (Sandbox Code Playgroud)
但是,我在UnityContainer类定义中找不到该方法.我只能看到:
public class UnityContainer : IUnityContainer, IDisposable
{
// Other methods
public object Resolve(Type t, string name, params ResolverOverride[] resolverOverrides);
public IEnumerable<object> ResolveAll(Type t, params ResolverOverride[] resolverOverrides);
// Other methods
}
Run Code Online (Sandbox Code Playgroud)
我使用了错误的包裹还是什么?
这些是我安装的包.
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
Run Code Online (Sandbox Code Playgroud) 用3个参数注册通用类的方法是什么
public interface ITest<T,V,VE>
{
}
public class TestRespository<T,V,VE>:ITest<T,V,VE>
{
}
Run Code Online (Sandbox Code Playgroud)
我是这样注册的
services.AddScoped(typeof(ITest<,,>), typeof(ITest<,,>));
Run Code Online (Sandbox Code Playgroud)
但无法进入构造函数以及
service.GetService(typeof(ITest<TestClass, vTestClass, VETestClass>)) as ITest<TestClass, vTestClass, VETestClass>;
Run Code Online (Sandbox Code Playgroud) 我在 IoC 方面遇到了一些麻烦 - 特别是使用 Unity。
假设我有一个应用程序要用来发送电子邮件。我会像这样建模:
public interface IEmailSender
{
void SendEmail();
}
Run Code Online (Sandbox Code Playgroud)
然后创建接口的一些实现:
public class GmailEmailSender : IEmailSender
{
public void SendEmail()
{
//code to send email using Gmail
}
}
public class YahooEmailSender : IEmailSender
{
public void SendEmail()
{
//code to send email using Yahoo
}
}
Run Code Online (Sandbox Code Playgroud)
我还有一门课来实际发送电子邮件
public class EmailSender
{
IEmailSender _emailSender;
public EmailSender(IEmailSender emailSender)
{
_emailSender= emailSender;
}
public void Send()
{
_emailSender.SendEmail();
}
}
Run Code Online (Sandbox Code Playgroud)
所以我了解如何配置 Unity 以始终使用其中一种实现:
IUnityContainer container = new UnityContainer().RegisterType<IEmailSender, …Run Code Online (Sandbox Code Playgroud) c# dependency-injection inversion-of-control unity-container
我试图模拟一个统一容器 - 我使用Moq并得到这个错误
System.ArgumentException: Invalid setup on a non-overridable member:
c => c.Resolve<ILogisticsAdapter>(new [] {})
Run Code Online (Sandbox Code Playgroud)
这是我测试的设置部分的代码.
var mockContainer = new Mock<IUnityContainer>();
mockContainer.Setup(c => c.Resolve<ILogisticsAdapter>()).Returns(logicsticsAdapter);
IUnityContainer container = mockContainer.Object;
Run Code Online (Sandbox Code Playgroud)
我错过了什么?我不是一般的模拟或单元测试的主人,但从我能说的这应该工作......
以防万一我使用VS2010和MS测试...
谢谢
这是整个测试夹具 - 你可以看到我已经改变它以使用真正的统一容器,但理想情况下我不想创建一个真正的统一容器 - 它不是我正在测试的.但是你可以看到我注释掉的代码......
[TestMethod]
public void WhenContructed_AdapterGetsSet()
{
//Prepare
ILogisticsAdapter logicsticsAdapter = new Mock<ILogisticsAdapter>().Object;
var mockEventAggregator = new Mock<IEventAggregator>();
mockEventAggregator.Setup(x => x.GetEvent<SetHelpMessageEvent>()).Returns(new SetHelpMessageEvent());
IEventAggregator eventAggregator = mockEventAggregator.Object;
IRegionManager regionManager = new Mock<IRegionManager>().Object;
//var mockContainer = new Mock<IUnityContainer>();
//mockContainer.Setup(c => c.Resolve<ILogisticsAdapter>(null)).Returns(logicsticsAdapter);
//IUnityContainer container = mockContainer.Object;
IUnityContainer container = …Run Code Online (Sandbox Code Playgroud) 只是想知道P&P Unity是否仍在继续工作,即使它只是由社区进行,或者P&P仍在推进它.
我现在正试图绕过IoC,我就是那里的一部分.我在SO的另一篇文章中找到的一个例子是:
http://blog.vascooliveira.com/unity-tutorial-and-examples/
我不太了解的是:
ILogger myExampleInstance = myContainer.Resolve(loggerType);
Run Code Online (Sandbox Code Playgroud)
我不确定loggerType是什么,因为它没有在任何地方提到它.
我可以看到,在这种情况下,IoC允许我们创建一种编写日志的方法.我们不是在代码中实例化特定类型的记录器,而是使用IoC来创建ILogger接口,然后我们对其进行编码.这意味着我假设我们并不特别关心使用什么类型的Logger.如果我们不在乎,我很想知道为什么我们需要传递一个loggerType,或者我们如何知道loggerType是由于关注点的分离.
我是理解它的一半,但我只需要最后的推动!=)
我得到"NullReferenceException:对象引用没有设置为对象的实例",我不知道我的代码有什么问题:
我有一个班级"EnemyInfo"
public class EnemyInfo {
public GameObject enemyObject;
}
Run Code Online (Sandbox Code Playgroud)
在另一个类"敌人"中,我使用它是这样的:
public class Enemies : MonoBehaviour {
public static List<GameObject> gos;
public static List<EnemyInfo> gosN = new List<EnemyInfo>();
void FixedUpdate() {
gos = new List<GameObject>(GameObject.FindGameObjectsWithTag("enemy"));
gosN.Add(null)
gosN[0].enemyObject = gos[0].gameObject //here I am getting error, dont know y :S
}
}
Run Code Online (Sandbox Code Playgroud) 我有两个类库"MyLibrary.dll"和"MyLibraryEditor.dll"用于Unity运行时和编辑器扩展."MyLibrary.dll"中有几个类成员仅供"MyLibraryEditor.dll"使用.
我的第一个想法是使用internal关键字,因为我错误地认为这限制了命名空间的可见性.相反,很明显,此关键字限制了程序集的可见性.
在不损害性能的情况下,将对某些类成员的访问限制为"MyLibrary.dll"和"MyLibraryEditor.dll"的最佳方法是什么?此外,反思不是一种选择.
我很高兴根本不记录这些功能,但不幸的是,Intellisense(和MonoDevelop的等价物)展示了这些成员.
我有一个类需要很多依赖 - 在我看来,很多依赖是8和更多.它在IDE中看起来很难看,因为它会破坏行,在一种情况下我有3行构造函数签名:
第一步
public class FooClass
{
public FooClass(IDependency1 dependency1, IDependency2 dependency2, ..., IDependency8 dependency8, IDependency9 dependency9)
{
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
我决定停止使用这种方法并创建依赖项字典.我取得了什么?漂亮的构造函数签名,但更容易获得运行时异常的可能性.
第二步
public class FooClass2
{
private IDictionary<Type, object> dependencyDictionary;
public FooClass2(IDictionary<Type, object> dependencyDictionary)
{
this.dependencyDictionary = dependencyDictionary;
...
}
...
public T GetObject<T>()
{
return (T)this.dependecyDictionary.FirstOrDefault(t => t.Key == typeof(T));
}
// USAGE
public void FooMethod()
{
IDependency1 = this.GetObject<IDependency1>();
...
}
}
Run Code Online (Sandbox Code Playgroud)
但是注册这种类型现在很难看.作为一个例子,我使用的是AutoFac,但任何其他依赖容器具有相同的行为.
var builder = new ContainerBuilder();
builder.Register(c => new FooClass2(new Dictionary<Type, …Run Code Online (Sandbox Code Playgroud) c# dependencies dependency-injection unity-container autofac
unity-container ×10
c# ×9
asp.net-mvc ×2
.net ×1
asp.net-core ×1
autofac ×1
c#-4.0 ×1
dependencies ×1
dll ×1
mono ×1
monodevelop ×1
moq ×1
mstest ×1