Navcomp
Navcomp

Reputation: 61

StructureMap constructor arguments are applied to properties

I am registering a class with StructureMap that includes a TimeSpan in the constructor parameters and another TimeSpan as a property of the class. When I use a named constructor argument in StructureMap the value for the constructor argument is applied to my constructor parameter and any public class properties that are TimeSpans. I also tried switching the class to DateTimes instead of TimeSpans and got the same result. So my question is, am I using StructureMap correctly or should I register this class another way? Thanks!

The following is a simple interface and class to demonstrate the problem:

public interface ITimeSpanTest
{
  TimeSpan Timeout { get; set; }
  TimeSpan LogTimeout { get; set; }
}

public class TimeSpanTest : ITimeSpanTest
{
  public TimeSpan LogTimeout { get; set; }
  public TimeSpan Timeout { get; set; }

  public string Process { get; set; }

  public TimeSpanTest(TimeSpan logTimeout, string process)
  {
    this.Timeout = TimeSpan.FromSeconds(1);
    this.LogTimeout = logTimeout;
    this.Process = process;
  }
}

and this is the StructureMap registration code

Container container = new Container();

container.Configure(c =>
{
  c.Scan(x =>
  {
    x.TheCallingAssembly();
  });

  c.For<ITimeSpanTest>().Use<TimeSpanTest>()
    .Ctor<TimeSpan>("logTimeout").Is(TimeSpan.FromMinutes(5))
    .Ctor<string>("process").Is("Process")
    .Singleton();
});

This is the output of StructureMap's container.Model.For().Default.DescribeBuildPlan() function

PluginType: SMTest.ITimeSpanTest
Lifecycle: Singleton
new TimeSpanTest(TimeSpan, String process)
  ? TimeSpan = Value: 00:05:00
  ? String process = Value: Process
Set TimeSpan LogTimeout = Value: 00:05:00
Set TimeSpan Timeout = Value: 00:05:00

As you can see the "logTimeout" name for the TimeSpan constructor argument seems to be ignored. The Timeout property is being set to 00:05:00 when it should be 00:00:01. I am using StructureMap 3.1.6.186.

Upvotes: 4

Views: 289

Answers (1)

Navcomp
Navcomp

Reputation: 61

I didn't get an answer here, but I posted to the StructureMap Google Group. The answer from Jeremy Miller is at

https://groups.google.com/forum/#!topic/structuremap-users/4wA737fnRdw

Basically, this is a known issue and probably won't be fixed as it is easy to work around by making Timeout read only. This can be done by removing the set in the Timeout property. For example,

public interface ITimeSpanTest
{
  TimeSpan Timeout { get; }
  TimeSpan LogTimeout { get; set; }
}

public class TimeSpanTest : ITimeSpanTest
{
  public TimeSpan LogTimeout { get; set; }
  public TimeSpan Timeout { get; }

  public string Process { get; set; }

  public TimeSpanTest(TimeSpan logTimeout, string process)
  {
    this.Timeout = TimeSpan.FromSeconds(1);
    this.LogTimeout = logTimeout;
    this.Process = process;
  }
}

In this particular case that worked fine. Ultimately, this issue seems to be that the StructureMap setter injector is applying the logTimeout setting to all public TimeSpan properties. I have also tested with DateTime which exhibits that same behavior. However, float and int types do not. This occurs in the last few versions of StructureMap 3 and the latest version of 4.

Upvotes: 2

Related Questions