有人可以帮忙吗?
我有一个wpf应用程序(应该没关系),在Onstart我有我的bootstrap东西..就像这样..
// Create unity container my service and repository
container = new UnityContainer()
.RegisterType<ISecurityRepository, SecurityRepository>()
.RegisterType<ISecurityService, SecurityService>();
Run Code Online (Sandbox Code Playgroud)
基本上ISecurityService希望我传入一个ISecurityRepository,因此上面的失败.
但我有点困惑,我是否必须创建一个新的IsecurityRespository然后传入它,这会失败对象不是吗?
无论如何我说"从容器传入SecurityService ISecurityRepository",但它还没有建成?
有任何想法吗?
有了StackOverflow的一些帮助,我有Unity Framework来创建我的链接依赖项,包括一个Entity Framework datacontext对象:
using (IUnityContainer container = new UnityContainer())
{
container.RegisterType<IMeterView, Meter>();
container.RegisterType<IUnitOfWork, CommunergySQLiteEntities>(new ContainerControlledLifetimeManager());
container.RegisterType<IRepositoryFactory, SQLiteRepositoryFactory>();
container.RegisterType<IRepositoryFactory, WCFRepositoryFactory>("Uploader");
container.Configure<InjectedMembers>()
.ConfigureInjectionFor<CommunergySQLiteEntities>(
new InjectionConstructor(connectionString));
MeterPresenter meterPresenter = container.Resolve<MeterPresenter>();
Run Code Online (Sandbox Code Playgroud)
这非常适合创建我的Presenter对象并显示相关视图,我真的很高兴.
但是,我现在遇到的问题是创建和处理Entity Framework对象的时间(我怀疑这将适用于任何IDisposable对象).像这样使用Unity,SQL EF对象"CommunergySQLiteEntities"是立即创建的,因为我已将其接口IUnitOfWork添加到MeterPresenter的构造函数中
public MeterPresenter(IMeterView view, IUnitOfWork unitOfWork, IRepositoryFactory cacheRepository)
{
this.mView = view;
this.unitOfWork = unitOfWork;
this.cacheRepository = cacheRepository;
this.Initialize();
}
Run Code Online (Sandbox Code Playgroud)
我当时对此感到有点不安,因为我不想保持打开数据库连接,但我看不到使用Unity依赖注入的任何其他方式.果然,当我实际尝试使用datacontext时,我收到此错误:
((System.Data.Objects.ObjectContext)(unitOfWork)).Connection
'((System.Data.Objects.ObjectContext)(unitOfWork)).Connection'
threw an exception of type 'System.ObjectDisposedException'
System.Data.Common.DbConnection {System.ObjectDisposedException}
Run Code Online (Sandbox Code Playgroud)
我对IoC原理的理解是,您将所有依赖项设置在顶部,解决您的对象并远离您.但是,在这种情况下,某些子对象(例如datacontext)不需要在创建父Presenter对象时初始化(就像在构造函数中传递它们一样),但是Presenter确实需要了解IUnitOfWork在与数据库通信时使用的类型.
理想情况下,我想在我解决的Presenter中找到这样的东西:
using(IUnitOfWork unitOfWork = new NewInstanceInjectedUnitOfWorkType())
{
//do unitOfWork stuff
}
Run Code Online (Sandbox Code Playgroud)
因此,Presenter知道IUnitOfWork实现用于直接创建和处理的内容,最好是从原始的RegisterType调用.我是否必须在我的Presenter中放置另一个Unity容器,否则可能会产生新的依赖关系?
对于IoC大师来说,这可能是非常明显的,但我真的很欣赏指向正确方向的指针.
如何配置Unity,以便从某个基类派生的任何类都将通过为基类定义的注入管道.
public abstract class Base
{
public IDependency Dependency {get;set;}
};
public class Derived1: Base
{
};
public class Derived2: Base
{
};
container.RegisterType<Base>(new InjectionProperty("Dependency", new ResolvedParameter<IDependency>()));
var d1 = container.Resolve<Derived1>();
Run Code Online (Sandbox Code Playgroud)
因此,我需要在解析派生类的同时向Unity 注册基类,以便为基类指定的所有注入都将应用于派生类.
DependencyAttribute由于我的项目限制,不允许装饰基类属性.
我有一个类在其构造函数中有一些原始类型参数,如字符串等.
我应该如何使用统一容器注册类型?
public LoginManager(
IRegionManager regionManager,
IEventAggregator eventAggregator,
string mainRegionName,
Uri login,
Uri target)
{
this.regionManager = regionManager;
this.eventAggregator = eventAggregator;
this.mainRegionName = mainRegionName;
this.login = login;
this.target = target;
}
}
Run Code Online (Sandbox Code Playgroud)
更新:
Remeber的IRegionManager和IEventAggregator已知类型的棱镜UnityBootstrapper这是在我的情况下,容器包装.我必须重新注册吗?我想保持类型注册尽可能简单.
这会被视为坏习惯吗?有更好的选择吗?
我试图在Unity中复制以下Ninject语法,但没有任何运气:
Bind<IIdentity>().ToMethod(c => HttpContext.Current.User.Identity);
Run Code Online (Sandbox Code Playgroud)
我认为应该看起来像:
IUnityContainer container;
...
container.RegisterType<IIdentity>(HttpContext.Current.User.Identity);
Run Code Online (Sandbox Code Playgroud)
应该怎么样?
有很多帖子显示了如何手动完成 - 顺便说一下,我以前做过 - 但我很惊讶地发现没有Nuget软件包以类似的方式将此功能添加到您的WCF项目中您可以使用Unity.MVC3将Unity添加到MVC3项目中.我搜索了在线Nuget包源目录,但没有得到什么.如果我错过了一些明显的东西,如果你指出我正确的方向,我会很感激.
wcf dependency-injection inversion-of-control unity-container nuget
我已经阅读了一些指出如何做到这一点的文章,即:
这些看起来效果很好,但是当我遵循这里的一些指导原则时
我好像来了一个收割机.对我来说,问题是当我将AuthorizationAttribute添加为GlobalFilter而不是仅仅装饰控制器/操作时.虽然依赖解析器似乎被调用并设置我公开的[Dependancy]属性,当它实际到达我覆盖AuthorizeAttribute的OnAuthorization()方法的代码部分时,我的public [Dependency]属性为null.
当我从全局过滤器中删除它并装饰一个控制器它似乎工作.
如果需要更多信息,我可以发布代码.
编辑:为了进一步扩展这里我的一些代码:
的global.asax.cs
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
// If I have this here the my [Dependency] attribute does not keep it's value
// If I remove it and decorate the controller the [Dependency] attribute keeps it value
filters.Add(new BasicAuthenticationAttribute());
filters.Add(new HandleErrorAttribute());
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// injection of services and data contexts
var container = new UnityContainer();
// injections for services
RegisterUnityServices(container);
// …Run Code Online (Sandbox Code Playgroud) 我使用EntityFramework和实施了一堆后台作业类的通用存储库和单元的工作模式.使用Unity DI创建作业类,以便可以向它们注入依赖项,这些依赖项主要是存储库和UnitOfWork对象.存储库和工作单元应共享EF DbContext.
一个常见的工作看起来像这样:
public class CommonJob : IJob, IDisposable
{
private IRepo<SomeEntity> _repo;
private IUnitOfWork _uow;
public CommonJob(IRepo<SomeEntity> repo, IUnitOfWork uow)
{
_repo = repo;
_uow = uow;
}
public void RunJob()
{
// do stuff here
}
public void Dispose()
{
_uow.Commit();
_uow.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
所有工作都在新任务中运行,就像这样
Task.Factory.StartNew(() => {
// container is UnityContainer
var job = container.Resolve<CommonJob>();
job.RunJob();
job.Dispose();
});
Run Code Online (Sandbox Code Playgroud)
我已经使用Unity注册了工作单元和存储库PerThreadLifetimeManager,认为这样可以在一个任务(以及一个作业对象)的上下文中共享已注册的实例,但不能在外部.
我遇到的问题是,有时工作会注入被处理的对象,这显然不是很好.我一直在阅读Task.Factory.StartNew()并不总是使用新线程.这是否意味着PerThreadLifetimeManager将在任务之间共享对象?如果这是真的,有没有另一种方法来统一管理对象生命周期,这将允许每个任务孤立地工作,无论它运行的线程是什么?
编辑:
虽然下面选择的答案将实现相同的目的,但我最终使用HierarchicalLifetimeManager和子容器来实现每个作业的依赖性隔离.
这是一个例子: …
c# dependency-injection .net-4.0 unity-container task-parallel-library
我有一个自定义MembershipProvider类,它继承自MembershipProvider,它带有两个参数:
public class CustomMembershipProvider : MembershipProvider
{
private readonly ISecurityRepository _securityRepository;
private readonly IUserRepository _userRepository;
public CustomMembershipProvider(ISecurityRepository securityRepository, IUserRepository userRepository)
{
...
}
public override MembershipUser GetUser(string username, bool userIsOnline)
{
...
}
... etc
}
Run Code Online (Sandbox Code Playgroud)
这个配置文件看起来类似于:
<membership defaultProvider="CustomMembershipProvider">
<providers>
<clear />
<add name="CustomMembershipProvider" type="Library.Membership.CustomMembershipProvider" />
</providers>
</membership>
Run Code Online (Sandbox Code Playgroud)
这在我的Web应用程序中主要用于登录和注销.我正在使用Unity for DI并在我的Boostrapper.cs类中设置必要的类.
但是,当我想创建一个自定义User类并调用Membership.GetUser方法时,我最近遇到了一个问题.当我这样做时,我得到以下异常:
{"No parameterless constructor defined for this object. (C:\\*app path*\\web.config line 43)"}
Run Code Online (Sandbox Code Playgroud)
我的配置文件中的第43行指向我上面发布的自定义成员资格提供程序.我认为在其他地方,应用程序使用Unity来解析这些参数,但是在使用Membership类时却没有.
有什么办法可以告诉应用程序如何解决这些依赖关系,或者如果没有办法在不使用具体实现的情况下将这些依赖关系添加到我的成员资格提供程序中?
编辑1:
这是自定义User类:
public class User : MembershipUser
{
public int UserId { get; …Run Code Online (Sandbox Code Playgroud) c# asp.net-mvc dependency-injection asp.net-membership unity-container
在Unity中,据我所知,我可以使用以下两个选项来注册单例实例:
IConfiguration globalConfig = new Configuration();
container.RegisterInstance<IConfiguration>(globalConfig);
container.RegisterType<IConfiguration, Configuration>(new ContainerControlledLifetimeManager());
Run Code Online (Sandbox Code Playgroud)
这两种方式有什么区别吗?注册单例实例的首选方法是什么?
unity-container ×10
c# ×7
.net ×2
.net-4.0 ×1
asp.net-mvc ×1
iidentity ×1
inheritance ×1
ninject ×1
nuget ×1
prism ×1
singleton ×1
wcf ×1