7

I'm using structure map with the AspNet Core 1.0 RTM. It appears they have removed using the FromServices attribute on properties. This breaks the code below because I am now unable to inject the ClaimsPrincipal. I'm not sure how to get the DI system to pickup this property. Do I need to create a custom InputFormatter or something else. That seems like a lot of work to get this working again.

Startup.cs

public class Startup {
    public IServiceProvider ConfigureServices(IServiceCollection services) {
        var container = new Container();
        container.Configure(i => {

            i.For<IHttpContextAccessor>()
                .Use(new HttpContextAccessor());

            i.For<ClaimsPrincipal>()
                .Use(x => x.GetInstance<IHttpContextAccessor>().HttpContext.User);
        });

        container.Populate(services);

        return container.GetInstance<IServiceProvider>();
    }
}

Model.cs

public class Model {
    //[FromServices] <-- worked in RC1
    public ClaimsPrincipal Principal { get; set; }

    public string Value => Principal.Identity.Name; 
}

TestController.cs

public class TestController : Controller {

    public IActionResult Test(Model model){
        return Ok();
    }
}
Phil
  • 4,134
  • 4
  • 23
  • 40
  • If you need dependencies in your model, you have architectural problems and need to rethink your design. Models shouldn't have dependencies and property injection is likely to hide dependencies, making testing and error tracking a nightmare. Property Injection is only used for rare corner cases where you have no control of the object created (i.e. WCF service proxies that are created where you have no way to use constructor injection) – Tseng Jul 12 '16 at 22:36

1 Answers1

5

As far as I know, one of the main reasons this was removed is because of the confusion surrounding where it works and where not. For example, FromServices was MVC's model binding concept and some users tried using it outside MVC and found it to not work.

You can however create your own model binding attribute to achieve a similar behavior.

For example, this works with decoration on a model..NOTE I haven't tested wit on a controller's property.

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FromDIAttribute : Attribute, IBindingSourceMetadata
{
    public BindingSource BindingSource { get { return BindingSource.Services; } }
}

public class Customer
{
    [FromDI]
    public IFooService FooService { get; set; }

    public string Name { get; set; }
}

UPDATE:

Found the announcement about its removal over here: https://github.com/aspnet/Announcements/issues/115

Kiran
  • 56,921
  • 15
  • 176
  • 161