标签: structuremap

您使用新的Fluent接口配置IOC容器的惯例/习语/模式是什么

我正在将大量代码移到Castle Trunk中,其中包括用于配置容器的新流畅界面.由于该项目有一个超出维护的巨大windsorConfig xml文件,我想我会开始利用这个新功能.我知道其他容器(例如StructureMap 2.0)也包含用于容器配置的流畅接口,所以这个问题不是基于Windsor.

我的问题是你使用新的流畅样式接口用于容器配置的约定/习语/模式是什么?

我的第一个想法是在某处创建一个静态方法(例如ContainerConfig.Config),它会将应用程序使用的所有相关类型加载到容器中.我担心最终这个单片函数最终会像xml配置文件一样难以维护(减去尖括号税).

我的第二个想法是将其分解,因此每个依赖程序集按照惯例导出其默认配置.我可以看到这对程序集内部使用的层次结构很有用.但对于外部使用的类型,是否应该在内部定义配置?

我想的越多,我似乎提出的问题就越多.你对此有什么想法?

.net structuremap fluent-interface inversion-of-control

6
推荐指数
1
解决办法
778
查看次数

使用StructureMap在模型 - 视图 - 展示器模式中进行Presenter注入

我已经实现了我自己的模型视图演示者模式的副本(在Web客户端软件工厂的静脉中),所以我可以利用我自己的DI框架而不是绑定到WCSF的ObjectBuilder,我遇到了很多问题.我想出了几个方法来做到这一点,但没有一个特别让我开心.我想知道是否有其他人有其他想法.

解决方案#1a

使用HttpModule拦截context.PreRequestHandlerExecute来调用ObjectFactory.BuildUp(HttpContext.Current.Handler)

public partial class _Default : Page, IEmployeeView
{
    private EmployeePresenter _presenter;

    private EmployeePresenter Presenter
    {
        set
        {
            _presenter = value;
            _presenter.View = this;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

解决方案#1b

在页面加载中调用buildup而不是使用HttpModule

public partial class _Default : Page, IEmployeeView
{
    private EmployeePresenter _presenter;

    private EmployeePresenter Presenter
    {
        set
        {
            _presenter = value;
            _presenter.View = this;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        ObjectFactory.BuildUp(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

解决方案#1c

如果需要,通过Property访问presenter允许Getter to BuildUp.

public partial class _Default : Page, IEmployeeView
{
    private EmployeePresenter …
Run Code Online (Sandbox Code Playgroud)

c# structuremap mvp dependency-injection

6
推荐指数
1
解决办法
3319
查看次数

如何在StructureMap Registy构造函数中获取实例?

如何在StructureMap Registy构造函数中获取某种类型的实例(在不同的注册表中注册)?我想使用这样的代码:

    public RepositoriesRegistry()
    {
        IApplicationSettings lApplicationSettings =
            ObjectFactory.GetInstance<IApplicationSettings>();
        Debug.Assert(lApplicationSettings != null);

        const string cSupportedDevicesConnectionString =
            "metadata=res://*/Models.SupportedDevices.Database.SupportedDevicesModel.csdl|res://*/Models.SupportedDevices.Database.SupportedDevicesModel.ssdl|res://*/Models.SupportedDevices.Database.SupportedDevicesModel.msl;provider=System.Data.SqlClient;provider connection string=\"{0}\"";
        string lSupportedDevicesConnectionString =
            string.Format(cSupportedDevicesConnectionString, lDatabaseConnectionString);
        SupportedDevicesEntities lSupportedDevicesEntities =
            new SupportedDevicesEntities(lSupportedDevicesConnectionString);
        ForRequestedType<SupportedDevicesEntities>().TheDefault.IsThis(
            lSupportedDevicesEntities);
        ForRequestedType<ISupportedDevicesRepository>().TheDefault.IsThis(
            new SupportedDevicesRepository(lSupportedDevicesEntities));

    }
Run Code Online (Sandbox Code Playgroud)

IApplicationSettings是应用程序设置的接口.实现此接口的具体类型(当前为ConfigFileApplicationSettings类)在另一个注册表中注册,如下所示:

    public ApplicationServicesRegistry()
    {
        ForRequestedType<IApplicationSettings>().TheDefault.IsThis(
            new ConfigFileApplicationSettings());
    }
Run Code Online (Sandbox Code Playgroud)

这两个注册表都在Bootstrapper中注册:

        #region IBootstrapper Members

    public void BootstrapStructureMap()
    {
        ObjectFactory.Initialize(InitalizeStructureMapContainer);
    }

    #endregion

    #region Private properties

    private static bool HasStarted { get; set; }

    #endregion

    #region Private methods

    private void InitalizeStructureMapContainer(IInitializationExpression x)
    {
        x.IgnoreStructureMapConfig = true;
        x.AddRegistry<ViewModelRegistry>();
        x.AddRegistry<ApplicationServicesRegistry>();
        x.AddRegistry<RepositoriesRegistry>(); …
Run Code Online (Sandbox Code Playgroud)

.net structuremap

6
推荐指数
1
解决办法
3017
查看次数

在通用存储库中定义默认构造函数结构图

我有一个通用的IRepository,它有2个构造函数,一个没有参数,另一个有datacontext作为参数.我想在这种情况下使用无参数构造函数将结构图定义为远离.我想要一种方法来创建一个无参数的构造函数,我见过的其他解决方案,他们创建一个新的Datacontext并将其传递给具有参数的构造函数.

structuremap generics asp.net-mvc dependency-injection ioc-container

6
推荐指数
1
解决办法
787
查看次数

使用Factory获取Injected对象

使用Factory方法检索注入的对象是不错的做法,还是只使用DI框架中的工厂方法?

我正在使用结构图,我应该只使用ObjectFactory.GetInstance();还是应该创建工厂类并在此类中调用ObjectFactory.GetInstance();? 因为如果我调用ObjectFactory.GetInstance(); 在我的课程中,我将创建与DI框架的耦合?抱歉,如果我无知,我对这个概念不熟悉.谢谢!

.net c# structuremap dependency-injection

6
推荐指数
1
解决办法
265
查看次数

如何使用StructureMap将相同的接口映射到不同的ConcreteClasses?

在创建Controller1时,我希望IService将映射到ConcreteService1,将IPageService映射到ConcretePageService1

当创建Controller2时,我希望IService将映射到ConcreteService2,IPageService将映射到ConcretePageService2

我如何初始化ObjectFactory以便以上工作?

这意味着我以这种方式初始化ObjectFactory:

 ObjectFactory.Initialize(x =>
    {  
         x.For<IService>().Use<ConcreteService1>();
         x.For<IPageService>().Use<ConcretePageService1>();
    });
Run Code Online (Sandbox Code Playgroud)

但是,这始终映射ConcreteService1到IService和ConcretePageService1到IPageService无论控制器类型

public class Controller1 : Controller
{
    public Controller1(IService service, IPageService pageService)
    {
    }
}

public class Controller2 : Controller
{
     public Controller2(IService service, IPageService pageService)            
     {         
     }
}

public interface IService 
{
}
public class ConcreteService1:IService 
{
}
public class ConcreteService2:IService 
{
}

public interface IPageService 
{
}
public class ConcretePageService1:IPageService 
{
}
public class ConcretePageService2:IPageService 
{
}
Run Code Online (Sandbox Code Playgroud)

c# structuremap

6
推荐指数
1
解决办法
3774
查看次数

如何设置StructureMap 3生命周期

在StructureMap 2中我有这样的事情:

For<ILogger>().HybridHttpOrThreadLocalScoped().Use<Logger>();
Run Code Online (Sandbox Code Playgroud)

使用Structure Map 3时,我应该使用以下内容吗?

For<ILogger>().LifecycleIs<HybridLifecycle>().Use<Logger>();
Run Code Online (Sandbox Code Playgroud)

然后我尝试将相同的更改应用于:

For<IDispatcher>().Transient().Use<Dispatcher>();
Run Code Online (Sandbox Code Playgroud)

我无法使用:

For<IDispatcher>().LifecycleIs<Transient>().Use<Dispatcher>();
Run Code Online (Sandbox Code Playgroud)

为什么?

谢谢你,米格尔

structuremap structuremap3

6
推荐指数
1
解决办法
1171
查看次数

如何在structuremap中进行装饰?

我尝试装饰IProjectService但我找不到struturemap的文档

For<IProjectService>().Use<ProjectServiceLogDecorator>();
For<IProjectService>().Use<ProjectService>()
                      .DecorateWith((context, decorator) =>   
                                  context.GetInstance<ProjectServiceLogDecorator>());
Run Code Online (Sandbox Code Playgroud)

我做错了什么?

exeption:

检测到双向依赖关系!检查以下StructureMap堆栈跟踪:1.)新ProjectServiceLogDecorator(IRepository的默认,IUnitOfWork的默认,IProjectService的默认,的IPrincipal的默认,AuditEventLogger的默认)2.)3. Project.Services.Projects.ProjectServiceLogDecorator)实例Project.Services的.Projects.ProjectServiceLogDecorator 4.)Project.Services.Projects.IProjectService的FuncInterceptor:IContext.GetInstance()5.)Project.Services.Projects.ProjectService 6.)Project.Services.Projects.IProjectService的实例(Project.Services.Projects) .ProjectService)7.)新的UsersController(IUserService的默认值,IService的默认,IUserNotificationService的默认, IService的默认,IProjectService的默认,ILicenseGroupService的默认)8.)Project.Web.Api.Controllers.UsersController 9.)Project.Web.Api.Controllers.UsersController 10的实例)的容器.GetInstance(Project.Web.Api.Controllers.UsersController)

我找到了解决办法,但令人作呕的是:

For<IProjectService>().Use<ProjectService>().DecorateWith((ctx, service) => 
    new ProjectServiceLogDecorator(
        ctx.GetInstance<IRepository<Project>>(),
        ctx.GetInstance<IUnitOfWork>(),
        service,
        ctx.GetInstance<ILicenseService>(),
        ctx.GetInstance<IPrincipal>(),
        ctx.GetInstance<AuditEventLogger>()
    )
);
Run Code Online (Sandbox Code Playgroud)

c# structuremap dependency-injection

6
推荐指数
1
解决办法
1231
查看次数

StructureMap中的跨线程冲突

我有一个使用多个数据库分片的API应用程序,使用StructureMap进行依赖注入.每个API调用中所需的标头之一是a ShardKey,它告诉我此调用正在寻址的数据库.为了实现这一点,我有一个OwinMiddleware名为的类ShardingMiddleware,其中包含以下代码(为清晰起见,已剪切):

var nestedContainer = container.GetNestedContainer();
using (var db = MyDbContext.ForShard(shardKey)) // creates a new MyDbContext with connection string appropriate to shardKey
{
    nestedContainer.Configure(cfg => cfg.For<MyDbContext>().Use(db));
    await Next.Invoke(context);
}
Run Code Online (Sandbox Code Playgroud)

这在我的测试环境中运行良好,并通过了一系列集成测试.

但是集成测试实际上是单线程的.当我将其部署到QA环境中时,真正的应用程序通过多个同时呼叫击中我的API,事情开始变得梨形.Ferinstance:

System.ObjectDisposedException:无法访问已处置的对象.此错误的常见原因是处理从依赖项注入解析的上下文,然后尝试在应用程序的其他位置使用相同的上下文实例.如果您在上下文中调用Dispose()或将上下文包装在using语句中,则可能会发生这种情况.如果使用依赖项注入,则应该让依赖项注入容器负责处理上下文实例.

或者其他异常表明StructureMap没有MyDbContext可用的有效实例.

对我来说,似乎多个线程在某种程度上混淆了彼此的配置,但对于我的生活,我无法理解如何,因为我正在使用嵌套容器来存储每个API调用的数据库上下文.

有什么想法可能会出错吗?

更新:我还尝试将我的Db上下文抽象为一个接口.没有真正的区别; 我仍然得到错误

System.InvalidOperationException:尝试创建"SomeController"类型的控制器时发生错误.确保控制器具有无参数的公共构造函数.---> StructureMap.StructureMapConfigurationException:没有注册默认实例,无法自动确定类型'MyNamespace.IMyDbContext'

更新2:我解决了问题,但赏金仍然是开放的.请参阅下面的答案.

c# structuremap asp.net multithreading

6
推荐指数
1
解决办法
1126
查看次数

StructureMap .Net核心Windows服务嵌套容器

有很多文章讨论如何使用ASP.NET Core的Structure Map,但谈论控制台应用程序或Windows服务并不是很多.ASP.Net Core中的默认行为是StructureMap为每个HTTPRequest创建一个嵌套容器,以便每个HTTP请求只对实例化一个具体类.

我正在使用PeterKottas.DotNetCore.WindowsService nuget包创建.Net核心Windows服务.我使用这篇文章设置了StructureMap:https://andrewlock.net/using-dependency-injection-in-a-net-core-console-application/

我的Windows服务是在Timer上设置的,每X秒执行一次动作.我希望这些操作中的每一个都使用类似于ASP.NET的嵌套容器.换句话说,我希望在轮询传递完成后处理为轮询传递#1创建的所有内容.当轮询#2开始时,我想要实例化所有对象的新实例.但是,在单个轮询传递的范围内,我只希望创建每个对象的一个​​实例.

这样做的正确方法是什么?

这是我的程序类

public class Program
{
public static ILoggerFactory LoggerFactory;
public static IConfigurationRoot Configuration;

static void Main(string[] args)
{
    var applicationBaseDirectory = AppContext.BaseDirectory;
    string environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

    if (string.IsNullOrWhiteSpace(environment))
        throw new ArgumentNullException("Environment not found in ASPNETCORE_ENVIRONMENT");

    ConfigureApplication(applicationBaseDirectory, environment);
    var serviceCollection = ConfigureServices();
    var serviceProvider = ConfigureIoC(serviceCollection);
    ConfigureLogging(serviceProvider);

    var logger = LoggerFactory.CreateLogger<Program>();
    logger.LogInformation("Starting Application");

    ServiceRunner<IWindowsService>.Run(config =>
    {
        var applicationName = typeof(Program).Namespace;
        config.SetName($"{applicationName}");
        config.SetDisplayName($"{applicationName}");
        config.SetDescription($"Service that matches Previous Buyers to Vehicles In …
Run Code Online (Sandbox Code Playgroud)

c# structuremap windows-services dependency-injection .net-core

6
推荐指数
1
解决办法
649
查看次数