小编Ste*_*ven的帖子

如何使用Simple Injector模拟模块/安装程序/注册表

Autofac有模块,Windsor有安装程序和StructureMap注册表...使用Simple Injector如何将配置逻辑打包成可重用的类?

我试过了:

public interface IModule { }

public class FooModule : IModule
{
    public FooModule(SimpleInjector.Container container)
    {
        container.RegisterSingleton<IBar, Bar>();
        container.RegisterSingleton<IFoo, Foo>();
    }
}
Run Code Online (Sandbox Code Playgroud)

我在Composition Root中使用它:

public static void Main(string[] args)
{
    var container = new SimpleInjector.Container();
    container.RegisterCollection<IModule>(new FooModule(container));
    ...
}
Run Code Online (Sandbox Code Playgroud)

但是,FooModule取决于容器,可能不是一个好的做法...请参阅http://code.google.com/p/autofac/wiki/BestPractices:

如果组件依赖于容器,请查看它们如何使用容器来检索服务,并将这些服务添加到组件(依赖注入)构造函数参数中.

.net c# dependency-injection ioc-container simple-injector

13
推荐指数
1
解决办法
3854
查看次数

在城堡 - 温莎的多个装饰员模式

我们正在重新设计一些遗留软件以使其更易于测试,并决定使用Dependency-Injection和Castle.Windsor来帮助我们.

首先,我们的目标:*许多装饰器都在数据流上工作.*装饰器的多种组合是可能的,并且每种情况下的根节点可能需要从不同的位置获取数据.

从技术上讲,我们的设计如下:

interface IUpdateableValue<T> 
{
  T Get();
};
Run Code Online (Sandbox Code Playgroud)

我们有三组要检索的数据,包含许多组件,都实现了IUpdateableValue()(伪代码):

JsonParser(
    Decompressor(
        Decrypter(decryptionKey
            FileCache(filename, 
                HttpWebDownloader(url))))

XmlParser(
    Decompressor(
        Decrypter(decryptionKey2
            FileCache(filename2, 
                HttpWebDownloader(url2))))
Run Code Online (Sandbox Code Playgroud)

我无法将设计融入像Castle-Windsor这样的DI框架中.我怀疑其中一些可以由命名实例处理,但这对于这种用法来说似乎很臭.

这个想法是,例如JsonParser和XmlParser实例的"用户"不知道(或关心)数据是来自HttpUrl,文件还是神奇地从帽子中拉出来的.

我在想我们的设计有问题,但不确定如何修复它.

关于如何进步的任何想法?

.net c# dependency-injection castle-windsor ioc-container

13
推荐指数
1
解决办法
2495
查看次数

IoC:连接事件处理程序的依赖项

我正在构建一个WinForms应用程序,其UI只包含一个NotifyIcon动态填充的UI ContextMenuStrip.有一个MainForm共同持有的申请,但这是从来没有看见.

我开始尽可能安全地构建它(使用Autofac来处理对象图)并且对我的成功感到非常满意,即使使用O部分也相当不错.随着我目前正在实施的扩展,似乎我发现了我的设计中的一个缺陷,需要重新改造一下; 我想知道我需要去的方式但是有点不清楚如何准确定义依赖关系.

如上所述,菜单部分在启动应用程序后动态填充.为此,我定义了一个IToolStripPopulator接口:

public interface IToolStripPopulator
{
    System.Windows.Forms.ToolStrip PopulateToolStrip(System.Windows.Forms.ToolStrip toolstrip, EventHandler itemclick);
}
Run Code Online (Sandbox Code Playgroud)

将此实现注入到MainForm,并且Load()方法PopulateToolStrip()使用ContextMenuStrip表单中定义的处理程序调用.populator的依赖关系仅与获取用于菜单项的数据有关.

这个抽象通过一些进化步骤很好地工作,但是当我需要多个事件处理程序时,这已经不够了,例如因为我正在创建几个不同的菜单项组 - 仍然隐藏在单个IToolStripPopulator界面后面,因为表单不应该是完全关心这一点.

正如我所说,我想我知道一般结构应该是什么样的 - 我将IToolStripPopulator接口重命名为更具体的东西*并创建了一个新PopulateToolStrip()方法,其方法不接受EventHandler参数,而是将其注入到对象中(也允许更多关于实现所需的处理程序数量的更多灵活性等).这样,我的"最重要的" IToolStripPopulator可以很容易地成为任何数量的特定适配器的适配器.

现在我不清楚的是我应该如何解决EventHandler依赖项.我认为处理程序应该全部定义MainForm,因为它具有正确响应菜单事件所需的所有其他依赖项,并且它还"拥有"菜单.这意味着我IToolStripPopulator最终注入到MainForm中的MainForm对象的依赖关系需要依赖于对象本身Lazy<T>.

我的第一个想法是定义一个IClickHandlerSource接口:

public interface IClickHandlerSource
{
    EventHandler GetClickHandler();
}
Run Code Online (Sandbox Code Playgroud)

这是由我实现的MainForm,我的具体IToolStripPopulator实现依赖于Lazy<IClickHandlerSource>.虽然这有效,但它是不灵活的.我要么必须为可能越来越多的处理程序定义单独的接口(严重违反OCP与MainForm类)或不断扩展IClickHandlerSource(主要违反ISP).直接依赖事件处理程序在消费者方面看起来是一个好主意,但是通过惰性实例(或类似)的属性单独连接构造函数似乎非常混乱 - 如果可能的话.

我最好的打赌似乎是这样的: …

c# dependency-injection inversion-of-control winforms solid-principles

13
推荐指数
1
解决办法
2052
查看次数

与非Web应用程序等效的BuildManager.GetReferencedAssemblies

相比AppDomain.GetAssemblies(),BuildManager.GetReferencedAssemblies()(System.Web.Compilation.BuildManager)似乎是一种更可靠的方式来获得由在运行ASP.NET应用程序中引用的程序集,因为AppDomain.GetAssemblies()只得到"已经将组件已经被加载到此应用程序域的执行上下文".

迭代所有程序集是在DI容器中应用程序启动时动态注册类型的重要工具,特别是在应用程序启动期间,可能还有其他程序集未加载(不需要),组合根是第一个需要它们的人.因此,有一个可靠的方法来获取应用程序的引用程序集非常重要.

虽然BuildManager.GetReferencedAssemblies()对于ASP.NET应用程序来说是一种可靠的方法,但我想知道:有哪些替代方案可用于其他类型的应用程序,例如桌面应用程序,Windows服务和自托管WCF服务?

asp.net asp.net-mvc wcf winforms asp.net-web-api

13
推荐指数
1
解决办法
2523
查看次数

如何在每个请求上从IoC容器中解析Web API消息处理程序/ DelegatingHandler

这篇MSDN文章描述了如何在ASP.NET Web API中有效地使用HTTP消息处理程序来"装饰"请求.此外,本文还显示了以下代码,用于将自定义处理程序注册到Web API管道中:

config.MessageHandlers.Add(new MessageHandler1());
Run Code Online (Sandbox Code Playgroud)

我对这种方法的问题在于它将MessageHandler1有效地注册为单例.当处理程序本身没有状态且没有依赖关系时,这很好,但在基于SOLID设计原则的系统中,这些处理程序很可能具有自己的依赖关系,并且很可能这些依赖关系需要一个寿命短于单身人士.

如果是这种情况,则不应将此类消息处理程序创建为单例,因为通常,组件的生命周期永远不会超过其依赖项的生存期.

所以我的问题是,我们有什么替代方法来注册自定义消息处理程序,以便可以在每个请求中从IoC容器中解析它们?

c# asp.net dependency-injection inversion-of-control asp.net-web-api

13
推荐指数
1
解决办法
4441
查看次数

使用Unity 2d中的坐标系和游戏屏幕?

所以我在x/y坐标系对我有意义的其他平台上开发了游戏.左上角表示坐标为(0,0)且右下角为(宽度,高度)的游戏画面.现在我正试图跳转到Unity 2d,我无法理解游戏画面是如何工作的.如果我在屏幕上有一个背景对象和一个角色对象,当我移动角色时,他的x和y值会在-3和3之间变化...非常小的坐标,它与我设置的游戏分辨率不匹配( 1024×768).有没有很好的教程来理解Unity中的游戏网格?或者任何人都可以解释我如何能够完成我想要做的事情?

2d game-engine unity-game-engine

13
推荐指数
1
解决办法
1万
查看次数

在这种情况下,我怎么不使用DependencyResolver.Current.GetService(...)

按照我在这个线程中给出的建议[ Ninject UOW模式,用户通过身份验证后的新ConnectionString我现在明白我不应该使用以下行...

    var applicationConfiguration =
            (IApplicationConfiguration)
                DependencyResolver.Current.GetService(typeof(IApplicationConfiguration));
Run Code Online (Sandbox Code Playgroud)

......作为服务定位器是一种反模式.

但是在以下过程的情况下,如何实例化实现" IApplicationConfiguration "的具体对象,以便我可以使用该对象获取未知用户角色名称,或者使用它来分配我的原则的" ApplicationConfiguration "属性?

Global.asax中

public class MvcApplication : NinjectHttpApplication
{
    /// <summary>
    /// Handles the PostAuthenticateRequest event of the Application control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
    {
        String[] roles;
        var applicationConfiguration =
            (IApplicationConfiguration)
                DependencyResolver.Current.GetService(typeof(IApplicationConfiguration));
        var identity = HttpContext.Current.User.Identity;
        if (Request.IsAuthenticated)
        {
            roles = Roles.GetRolesForUser(identity.Name);
        }
        else
        {
            roles …
Run Code Online (Sandbox Code Playgroud)

c# dependency-injection anti-patterns ninject service-locator

13
推荐指数
1
解决办法
1万
查看次数

在Owin启动期间,Simple Injector无法为每个Web API请求注册类注入

我正在使用Owin,Web API,实体框架,ASP.NET身份创建API.我使用Simple Injector作为我选择的DI框架.

在Owin启动过程中,我想用一些示例数据为我的数据库设定种子.这由一个实现类处理IDatabaseInitializer,看起来像这样:

public class MyDbInitializer : DropCreateDatabaseAlways<MyDataContext>
{
    private readonly IUserManager _userManager;

    public MyDbInitializer(IUserManager userManager)
    {
        _userManager = userManager;
    }

    protected override void Seed(MyDataContext context)
    {
        SeedIdentities();
    }

    private void SeedIdentities()
    {
        var user = new User
        {
            UserName = "someUsername",
            Email = "some@email.com"
        };

        _userManager.CreateAsync(user, "Password");
    }
Run Code Online (Sandbox Code Playgroud)

IUserManager是ASP.NET Identiy UserManager类的代理,它间接依赖于IUnitOfWork.如果你想知道,IUserManager注册如下:

container.Register(typeof(IUserManager), 
    () => container.GetInstance<IUserManagerFactory>().Create());
Run Code Online (Sandbox Code Playgroud)

因为我想根据Web API请求使用单个工作单元,所以我已经注册了IUnitOfWork以下内容:

container.RegisterWebApiRequest<IUnitOfWork, MyUnitOfWork>();
Run Code Online (Sandbox Code Playgroud)

除了解析类中的IUserManager依赖项之外,这对于所有事情都很好MyDbInitializer.在应用程序启动期间,SimpleInjector失败并出现以下ActivationException:

SimpleInjector.ActivationException was …
Run Code Online (Sandbox Code Playgroud)

c# dependency-injection simple-injector asp.net-web-api owin

13
推荐指数
1
解决办法
5287
查看次数

Visual Studio 2015/C#6/Roslyn无法在PCL项目中编译XML注释

我刚刚安装了新版本的Visual Studio 2015社区版(RTM),我试图让我的开源项目在VS2015和C#6.0下运行.

我的一些.cs在项目中共享.这样我就可以构建PCL版本(功能有限)和核心库的"完整"版本.

但是出于某种原因,某些代码文件在整个项目中正确构建,但在PCL项目中构建时会失败(其中所有内容都在C#5和Visual Studio 2013下编译).cref在构建PCL版本时,编译器似乎无法解析XML注释.这是一个在我的机器上失败的简化代码示例:

/// <summary></summary>
public class A
{
    // Compile error on next line:
    /// <summary><see cref="Y(Type)"/>.</summary>
    public void X() { }

    /// <summary></summary>
    /// <param name="x"></param>
    public void Y(Type x) { }

    /// <summary></summary>
    /// <param name="i"></param>
    public void Y(int i) { }
}
Run Code Online (Sandbox Code Playgroud)

我得到的编译错误是:

CS1580参数的类型无效XML注释cref属性中的类型:'Y(Type)'SimpleInjector.PCL

奇怪的是,XML评论中的IntelliSense支持(哇!我们现在在XML评论中有智能感知!)实际上是可行的,并且该方法Y(Type)可以通过下拉列表进行选择.但选择此选项后,将生成编译错误(仅在PCL中).

我的问题当然是如何解决这个问题?这是个常见的问题吗?项目的配置可能与此有关吗?这是一个已知的错误?

c# c#-6.0 visual-studio-2015

13
推荐指数
1
解决办法
607
查看次数

何时使用TryAddSingleton或AddSingleton?

我注意到在一些.net核心示例中有调用 TryAddSingleton,有些是 AddSingleton在注册服务时.

如果服务类型尚未注册,则反编译器会显示TryAdd(由TryAddSingleton调用)将指定的参数"descriptor"添加到"集合".

这是否意味着使用TryAddSingleton总是更安全,以防某些其他方法/库已经注册了同一个类?

c# dependency-injection startup asp.net-core

13
推荐指数
1
解决办法
3940
查看次数