1

The title is a bit misleading, I am actually trying to learn how to use Castle Windsor and I think I understand registering the interfaces/objects.

What I can't seem to grasp is how to set properties dynamically at Runtime?

Below is my code, an IFileWriter interface implemented by the TextFileWriter concrete class.

Then I have the code for my test application to I've registered the interface and the object.

Now - how do I instantiate the TextFileWriter and set the FilePath, OutputFileName, and DataToWrite properties?

namespace IOCv2Library.Interfaces
{
    public interface IFileWriter
    {
        string OutputFileName { get; set; }
        string filePath { get; set; }

        DataTable DataToWrite { get; set; }

        void WriteFile();
    }
}

namespace IOCv2Library
{
    public class TextFileWriter : IFileWriter
    {
        private DataTable _dataTable = null;
        private string _filePath = String.Empty;
        private string _outputFileName = String.Empty;

        public DataTable DataToWrite
        {
            get{ return _dataTable; }

            set { _dataTable = value; }
        }

        public string filePath
        {
            get { return _filePath; }

            set { _filePath = value; }
        }

        public string OutputFileName
        {
            get { return _outputFileName; }

            set { _outputFileName = value; }
        }

        public void WriteFile()
        {
            string fullFileName = Path.Combine(new string[] { _filePath, _outputFileName });
            using (StreamWriter file =
            new StreamWriter(fullFileName, true))
            {
                foreach (DataRow drRow in _dataTable.Rows)
                {
                    foreach (DataColumn dcCol in _dataTable.Columns)
                    {
                        file.Write(drRow[dcCol].ToString() + "\t");
                    }
                    file.Write(Environment.NewLine);
                }
            }
        }
    }
}

namespace TestCastleWindsorIOCv2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var container = new WindsorContainer();
            container.Register(Component.For<IFileWriter>().ImplementedBy<IOCv2Library.TextFileWriter>());



        }
    }
}
  • In this case, you don't want Castle to inject these properties, unless you know what they are already when you register the component, which would make the component somewhat inflexible: you would instead resolve an instance of `ITextWriter` from the container - using a DI framework, a ServiceLocator, or even directly - and then you would set these properties on the instance you get back, and tell it to write the file. – stuartd Jun 16 '16 at 16:50
  • Ok - now THAT makes sense. – Dave Rancour Jun 16 '16 at 17:10

1 Answers1

0

This is a duplicate of Castle Windsor IoC Property Injection simple how-to

You need to have your root object resolved by Windsor for any injection (constructor or property) to work.

Property injection should also be used for non-required dependencies. If the dependencies is required, it should probably be injected using constructor injection.

You're unit tests shouldn't use a DI framework. They should just instantiate the object directly.

Community
  • 1
  • 1
Fran
  • 6,440
  • 1
  • 23
  • 35
  • I think the OP's not talking about unit tests. He's referring to a simple demo app to make use of the container. – Jan Köhler Jun 16 '16 at 16:45
  • Ah. i read test and thought it was a test. The answer is still valid. You aren't going to be able to test it like that in a web forms app. It would be easier to debug through in an MVC app. Create the container in global.asax. install your components. create a controller factory that leverages Windsor. modify the default controller with properties that are resolved through Windosr. – Fran Jun 16 '16 at 16:49
  • I've read that tutorial - it is NOT simple lol. Not for someone new to IOC containers. I can't seem to find any examples that make sense, and yes I'm trying to build a demo app to "see" how everything works and determine if the extra effort is worth it for my projects. Spefically I'll look into "create a controller factory that leverages Windsor" and " modify the default controller with properties that are resolved through Windosr". I think I'm missing the controller factory part. Also not using MVC, using WinForms as my test bed. – Dave Rancour Jun 16 '16 at 16:50
  • webforms makes it difficult to use an IOC container. Like I said above use use MVC for you test bed. There are a number of example of the steps I outlined on satckoverflow and the web to walk you though. here's one from windsor itself https://github.com/castleproject/Windsor/blob/master/docs/mvc-tutorial-intro.md – Fran Jun 16 '16 at 16:58
  • Why the MVC requirement? I want to get exposed to enough of the nitty gritty (IE I don't want anything happening for me automagically) and I don't do web very much. I'll look at the examples you mention but probably I've already read them. EDIT: Sorry, when I say MVC I always associate to web - I know that's not true. MVC is a general application development paradigm. I don't arrange most of my applications that way, I mostly do DLL's for system integrations. – Dave Rancour Jun 16 '16 at 17:04
  • 1
    Might want to have a look at [Using Castle.Windsor with Windows Forms Applications](http://stackoverflow.com/questions/4840849/using-castle-windsor-with-windows-forms-applications) – stuartd Jun 16 '16 at 17:09
  • because you need a place for windsor to create root objects so that it can then inject the dependencies. With MVC you can easily override the creation of controllers by replacing the default controller factory with the windsor one. The controller is the root object. – Fran Jun 16 '16 at 17:11
  • Like in the link from stuartd. this isn't true DI, but a service locator pattern. – Fran Jun 16 '16 at 17:11