我试图实现可能无法实现的目标。
我们有一个很棒的MVC 5应用程序。我创建了一个小型MVC项目来模拟和解释我想要应用到那个大型MVC项目中的内容。
我有一个具有唯一ID的控制器。在此示例项目中,为每个请求重新生成唯一ID。在MVC项目中,它有点复杂和不同。但是,它与此示例的范围无关。
public class FooController : Controller
{
public string UniqueId = Guid.NewGuid().ToString("N");
public ActionResult Index()
{
var worker = new WorkerA();
worker.DoWork();
return View();
}
}
FooController
创建WorkerA
,创建WorkerB
,创建WorkerC
,依此类推。工人不一样。他们没有相同的界面/实现。为了使示例简单,我使它们看起来很相似。
这里是工人:
public class WorkerA
{
public string UniqueId = string.Empty;
public void DoWork()
{
var worker = new WorkerB();
worker.DoWork();
//...
//...
}
}
public class WorkerB
{
public string UniqueId = string.Empty;
public void DoWork()
{
var worker = new WorkerC();
worker.DoWork();
}
}
我希望将属性UniqueId
注入到worker中,而不必将其作为参数传递。
我想避免这样做:
public WorkerA(string uniqueId)
{
UniqueId = uniqueId;
}
但我需要为所有其他工人做同样的事情。
修改
有没有办法用ninject来实现这个目标?
答案 0 :(得分:1)
您可以通过以下方式使用Microsoft.Practices.Unity实现所需目的:
public class WorkerA
{
[Dependency]
public string UniqueId { get; set; }
}
public class WorkerB
{
[Dependency]
public string UniqueId { get; set; }
}
之后:
var container = new UnityContainer();
container.RegisterType<WorkerA>(new InjectionProperty(nameof(WorkerA.UniqueId),"WorkerAValue"));
container.RegisterType<WorkerA>(new InjectionProperty(nameof(WorkerB.UniqueId), "WorkerBValue"));
稍后,您可以从容器中请求配置了所需属性的实例:
var workerA = container.Resolve<WorkerA>();
var workerB = container.Resolve<WorkerB>();
答案 1 :(得分:0)
您可以执行以下操作:
from tkinter import *
答案 2 :(得分:0)
您可以创建一个单例类来管理GUID并以这种方式将其传递给子类。这样你仍然可以在构造函数中执行它,但不必将其作为参数传递
public class GUIDManager
{
private static GUIDManager _instance;
private Guid _activeGuid;
public Guid ActiveGuid {
get { return _activeGuid; }
set { _activeGuid = value; }
}
private GUIDManager()
{
if (_activeGuid == null)
_activeGuid = new Guid();
}
public static GUIDManager GetInstance()
{
if(_instance == null)
{
_instance = new GUIDManager();
}
return _instance;
}
}
public class WorkerB
{
public string UniqueId = string.Empty;
public WorkerB()
{
var manager = GUIDManager.GetInstance();
UniqueId = manager.ActiveGuid.ToString();
}
public void DoWork()
{
var worker = new WorkerC();
worker.DoWork();
}
}
答案 3 :(得分:0)
根据您的问题,我不完全清楚同一个请求中的所有工作人员是否获得相同的ID。如果他们都应该获得相同的ID,那么这很简单:
将ID包装在课堂中并使用InRequestScope()
:
public class BrowserTabId
{
public string browserTabId;
public BrowserTabId(string tabId)
{
if(string.IsNullOrEmpty(tabId))
{
throw new NullArgumentException();
}
this.browserTabId = tabId;
}
public string Id { get { return this.browserTabId; } }
}
Bind<BrowserTabId>()
.ToMethod(ctx =>
new BrowserTabId(HttpContext.Items["BrowserTabId"] as string)))
.InRequestScope();
出于可测试性原因,您还可以打开接口IUniqueRequestId
并为其创建绑定。
这将导致在同一请求期间创建的所有工作人员/对象都收到相同的BrowserTabId
。如果您不想使用c-tor注射,可以使用属性注入。如果您不想注入所有类型的值,则使用When(..)
条件指定何时注入以及何时不注入。将此与null-object pattern相结合,以防止ninject抱怨它无法注入请求的类型。
按如下方式调整工人:
public class WorkerA
{
[Inject]
public BrowserTabId BrowserTabId { get; set; }
....
}
但是,请注意,为了使其正常工作,就像正常的构造函数注入一样,有必要由{ninject实例化WorkerA
或者通过Ninject.Inject(workerAInstance)
由于您提到实际应用程序中ID的生命周期稍微复杂一些,我猜您将不得不使用与InRequestScope
不同的内容 - 可能会推出自己的范围(使用InScope(...)
)。或许,InCallScope()
是可行的选择。但是,如果不知道你需要什么,那么建议你就有点困难了。