我正在为我的项目使用Unity App Block(版本1.2.0.0).我有一个Unity容器BuildUp方法的问题,我正在使用我的ascx控件.这是一些代码(非常简单)
public class BaseUserControl<T>:UserControl where T:class
{
protected override void OnInit(EventArgs e)
{
InjectDependencies();
base.OnInit(e);
}
protected virtual void InjectDependencies()
{
var context = HttpContext.Current;
if (context == null)
{
return;
}
var accessor = context.ApplicationInstance as IContainerAccessor;
if (accessor == null)
{
return;
}
var container = accessor.Container;
if (container == null)
{
throw new InvalidOperationException("No Unity container found");
}
container.BuildUp<T>(this as T);
}
}
Run Code Online (Sandbox Code Playgroud)
在我的解决方案中,在ascx控件的基本控件中调用此方法.这里应该注入儿童控制的属性:
[Dependency]
private IStock Stock { get; set; }
Run Code Online (Sandbox Code Playgroud)
因此,在建立股票房产后仍然是空的.Resolve方法适用于具有相同容器和配置的IStock.我尝试使用只有一个属性IStock的简单测试类进行构建并获得相同的结果.那么积累会有什么问题呢?
为什么我更喜欢Unity上的StructureMap?
我正在尝试将Unity 2.0用于我当前的MVC项目,并且无法在web.config文件中配置参数注入.
这就是我所拥有的:
1)家庭控制器:
public class HomeController : Controller
{
IRepository repository = null;
public HomeController()
{
// Always calls this constructor. Why?
// Should be calling the constructor below that takes IRepository.
}
public HomeController(IRepository repository)
{
// Should be calling this constructor!!!
this.repository = repository;
}
public ActionResult Index()
{
List<int> intList = this.repository.GetInts();
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
Run Code Online (Sandbox Code Playgroud)
一个带两个构造函数的基本控制器.第一个不带参数,第二个带IRepository作为参数(应该由Unity注入)
2)SQL存储库
public class SQLRepository : IRepository
{
private string connectionString = null;
public …Run Code Online (Sandbox Code Playgroud) 我们使用统一作为IoC.我们遇到了独特的问题.我们创建了名为IPlugin的接口.该接口在各种第三方供应商之间共享,以基于此接口开发自己的插件.然后这些插件适合我们的系统.供应商将提供他们的插件作为DLL.我们想要的是,使用unity我们想要解析用IPlugin接口实现的所有程序集类型.我发现这可以通过MEF导出属性实现,我想知道这是否可以通过Unity使用一些简短的扩展来实现.
我们的代码
Public interface IPlugin
{
Void ProcessData();
}
Public class DataProcessor
{
Var pluginList = unityContainer.ResolveAssemblies<IPlugIn>()
/*
There is no such method in unity but what we want is scan all assemblies in bin folder and load all types which are inheriting from IPlugIn
*/
}
Run Code Online (Sandbox Code Playgroud)
供应商的集会
Public class AbcCompanyPlugIn : IPlugin
{
Void ProcessData()
{
// some code
}
}
Public class XyzCompanyPlugIn : IPlugin
{
Void ProcessData()
{
// some code
}
}
Run Code Online (Sandbox Code Playgroud) 我正在注册这样的类型:
IUnityContainer container = new UnityContainer()
.RegisterType<IActiveDirectoryUser, ADUser>();
Run Code Online (Sandbox Code Playgroud)
ADUser类包含2个构造函数,一个无参数,一个具有单个参数.当解析器解决它时,它会选择带参数的解析器.如何告诉它使用无参数控制器?
看起来Unity似乎提供了两种不同的路线来实现AoP功能.
问题是为什么?有什么区别?每种方法的优缺点是什么?
例如,使用ICallHandler:
unity.Configure<Interception>()
.AddMatchingRule(
new TypeMatchingRule(typeof (ComplexEntity))
).AddMatchingRule(
new TypeMatchingRule(typeof (ComplexEntity.InnerEntity))
).AddMatchingRule(
new MemberNameMatchingRule("*")
).AddCallHandler(
new CallHandler()
);
Run Code Online (Sandbox Code Playgroud)
但是使用IInterceptionBehavior代替ICallHandler也可以实现类似的功能
unity.RegisterType<ComplexEntity,ComplexEntity>
(new VirtualMethodInterceptor(), new InterceptionBehavior)
Run Code Online (Sandbox Code Playgroud)
还有一个混合某处可以让你设置拦截,但使用一个调用处理程序,例如.
unity.Configure<Interception>()
.SetInterceptorFor<ComplexEntity>(new VirtualMethodInterceptor())
.AddPolicy("TestPolicy")
.AddMatchingRule(
new TypeMatchingRule(typeof (ComplexEntity))
).AddMatchingRule(
new TypeMatchingRule(typeof (ComplexEntity.InnerEntity))
).AddMatchingRule(
new MemberNameMatchingRule("*")
).AddCallHandler(
new CallHandler()
);
Run Code Online (Sandbox Code Playgroud)
那么哪一个使用?为什么在单一框架中存在看似冗余的解决方案?
c# aop dependency-injection unity-container unity-interception
我有一个简单的抽象工厂实现:
public abstract class ICarFactory{
public abstract ISportsCar CreateSportCar();
public abstract IFamilyCar CreateFamilyCar();
}
public abstract class ISportsCar {
public abstract void Accelerate();
}
public abstract class IFamilyCar {
public abstract void Accelarete();
}
public class BMWFactory : ICarFactory {
public override ISportsCar CreateSportCar() {
return new BMWi7();
}
public override IFamilyCar CreateFamilyCar() {
return new BMWM5();
}
}
public class WolksvagenFactory : ICarFactory {
public override ISportsCar CreateSportCar() {
return new WVGolfR();
}
public override IFamilyCar CreateFamilyCar() {
return …Run Code Online (Sandbox Code Playgroud) 我正在尝试熟悉asp.net mvc,目前正在设置日志记录。
我看了一下Microsoft.Extensions.Logging并阅读了有关如何设置它的信息,但我一直在努力统一类型注册。
我想为
public HomeController(ILogger<HomeController> logger)
Run Code Online (Sandbox Code Playgroud)
我可以这样
private static void RegisterLoggingTypes(IUnityContainer container)
{
ILoggerFactory loggerFactory = new LoggerFactory()
.AddConsole()
.AddDebug();
container.RegisterType<ILogger<HomeController>>(new InjectionFactory(c => loggerFactory.CreateLogger<HomeController>()));
}
Run Code Online (Sandbox Code Playgroud)
但是我不想为每种类型都声明一个。我试过了
container.RegisterType(typeof(ILogger<>), new InjectionFactory((c,t,s) => loggerFactory.CreateLogger(t)));
Run Code Online (Sandbox Code Playgroud)
但这返回的ILogger是一个ILogger(of HomeController)
知道我该怎么做吗?
谢谢
使用依赖注入创建应用程序时,它使用依赖注入的框架,例如Unity(或Ninject).
如何初始化一起开始将容器的接口注册到容器,并让它们可供应用程序在整个应用程序的运行生命周期中使用?
您是否需要将DI容器传递给可能使用依赖项注入的每个方法,或者是否有某种方法可以使容器全局可访问,以便您可以在开始时将它们全部注册在一起并在运行应用程序时访问它们而无需持续通过它们,并在需要时能够使用它们?
环境:Visual Studio 2015,C#,Microsoft Unity(用于DI容器)
示例代码
static void Main(string[] args)
{
// Make Unity resolve the interface, providing an instance
// of TrivialPursuit class
var diContainer = new UnityContainer();
diContainer.RegisterType<IGame, TrivialPursuit>();
var gameInstance = diContainer.Resolve<IGame>();
var xotherClass = new AnotherClass();
xotherClass.TestOtherClassOtherMethod();
}
Run Code Online (Sandbox Code Playgroud)
------没有依赖注入类上下文的另一个类------
public void TestOtherClassOtherMethod()
{
IGame gameInstance = -- -Container is Not available to resolve from in this class ---
}
Run Code Online (Sandbox Code Playgroud)
原因:我不想将以后可能需要的所有类型传递给我加载的每个类,我只想在需要时使用实例.我进入类越深入,随后应用程序变得越来越复杂,我不想将每个类型的实例从Main()方法传递给每个类.
如何在一个统一的容器中注册来自不同程序集的内部类?
UnityContainer container = new UnityContainer();
container.RegisterType<IPublicInterface, InternalClassImpl>(new ContainerControlledLifetimeManager());
Run Code Online (Sandbox Code Playgroud)
如果InternalClassImpl可以在其程序集外部访问,则效果很好,但是,如果在内部并实现IPublicInterface,则唯一可行的选择似乎是提供一个可以创建它们的工厂。
但是,如果您有一家工厂在创建类,那么如何继续将Dependency Injection与Unity一起使用以注入其依赖项?
Large Application
UnityContainer container = new UnityContainer();
container.RegisterType<IPublicInterface>(new InjectionFactory(c =>
InternalClassImplFactory.MakeInternalClassImpl()));
Run Code Online (Sandbox Code Playgroud)
Small Library
namespace SmallLibrary
{
public interface IPublicInterface
{
}
public class InternalClassImplFactory
{
public static IPublicInterface MakeInternalClassImpl()
{
return new InternalClassImpl();
}
}
internal class InternalClassImpl : IPublicInterface
{
public InternalClassImpl()
{
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果InternalClassImpl需要大型应用程序和内部SmallLibrary类的注入依赖项,会发生什么情况?
unity-container ×10
c# ×7
.net ×1
aop ×1
asp.net-mvc ×1
generics ×1
structuremap ×1
web-config ×1