views:

124

answers:

2

Hi All,
In my Asp.Net project I wanna use Property Auto-wiring, e.g. for my ILogger. Basically I placed it as Property into class where I need to use it. Like below.

public class UserControlBase : UserControl
{
    public ILogger CLogger { get; set; }
    ....
}


public partial class IPTracking : UserControlBase
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            string ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            //it works
            ILogger logger = ObjectFactory.GetInstance<ILogger>();
            logger.LogInfo(string.Format("Client IP: {0}", ip));
            //it does not work
            CLogger.LogInfo(string.Format("Client IP: {0}", ip));
        }
    }
}

However when calling in inherited control, logger is null. I checked the container and it'a definitely set as above implementation shows. Below is setting which is called from Global.asax.

    public static void SetupForIoC()
    {
        Debug.WriteLine("SetupForIoC");
        ObjectFactory.Initialize(x =>
        {
            x.FillAllPropertiesOfType<ILogger>().Use<EntLibLogger>();
        });

        Debug.WriteLine(ObjectFactory.WhatDoIHave());
    }

Thanks for any advice, tip? X.

Update:
- I didnt mentioned before, but its Asp.Net webforms 3.5.
- I can't see what I am missing. I guess it could be because the injection gets involved later in process and didnt get set in requested class.

Link to desc. of usage: http://structuremap.github.com/structuremap/ConstructorAndSetterInjection.htm#section7

A: 

Hey,

Where do you actually set the CLogger property on the user control? Also, if you wanted to use one logger within the page, you could have the User cotnrol do:

public ILogger CLogger
{
  get
  {
    if (this.Page is PageBase)
       return ((PageBase)this.Page).Logger;
    else
       return null;
  }
}
Brian
The point is I dont want to set it. I want to DI do it for me. According to StructureMap help it should work in this way. The logger itself is just used in code behind for simple logging (error, info, alerts)
Xabatcha
A: 

Give something like this a shot.

FillAllPropertiesOfType<ILogger>().AlwaysUnique().Use(s => s.ParentType == null ? new Log4NetLogger(s.BuildStack.Current.ConcreteType) : new Log4NetLogger((s.ParentType)));

Check out another StackOverflow answer I have which discusses using StructureMap to auto wire loggers.

KevM
I am sorry, I don't get it. Does suggested solution require to create specific constructor? I have currently only parameter less constructor for logging class (EntLibLogger). Is there specific need to inject required class into specific context?
Xabatcha
The log4net logger I was using can take a type as the scope for logging. It's nice to have your loggers scoped to your classes at times. Makes it super fast to get context about the problem. Not sure how you were scoping your loggers. If you have no need to control construction of your logger the FillAllPropertiesOfType<ILogger> should do what you need.
KevM