How to use ServiceStack Funq in my own projects
Asked Answered
O

2

12

At work we're doing several new web services projects in ServiceStack and taking advantage of Funq in some of them. I'm currently working on a separate project that will consume said web services and was wondering if there was a way for me to use ServiceStack's Funq in my project to resolve my dependencies as to use more or less the same patterns we're using when developing our web services.

Is this possible?

Optimistic answered 5/2, 2013 at 14:9 Comment(2)
Why do you think it is not possible? Funq is a DI container. You can add it to any project.Varicolored
Since there's no documentation available from the original project, I have no idea where to even begin. Also, I was wondering about using the version packed with ServiceStack, not the one on CodePlex.Optimistic
T
3

I'm in a similar position, wanting to use heaps of the ServiceStack tools in a non-webby project. I agree that there is a ... slight lack in documentation for Funq

I have been using it in a legacy WinForms app, trying to avoid changing the original project (too much) and I add the new forms to a new project.
I added references to most of the ServiceStack libraries to most of my projects (manually because I'm doing this in .Net 3.5)

Here is the code in the winforms Program.cs file; Note that the FunqContainer is a public static property - I'm still not sure about that, but it gives access across the whole project to the FunqContainer

using System;
using System.Threading;
using System.Windows.Forms;

using Funq;
using MyApp.Utilities;

static class Program
    {
        public static Funq.Container FunqContainer { get; set; }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            FunqContainer = new Container();
            FunqContainer.Init(); 

            etc...
        }
    }

FunqContainer.Init() is an extension method in my separate project for - you guessed it - initializing Funq

using System.Configuration; // Don't forget to ref System.Configuration.dll
using Funq;     
using ServiceStack.OrmLite;
using ServiceStack.OrmLite.SqlServer;

namespace MyApp.Utilities
{
    public static class FunqExtensions
    {
        public static void Init(this Container container)
        {
            //-------------------------------------------------------
            // NB - I don't particularly like AutoWiring the public properties. 
            // Usually I want private stuff in the constructor)
            //-------------------------------------------------------
            var sqlServerConnectionString = ConfigurationManager.ConnectionStrings["HowdyCS"];
            container.Register<IDbConnectionFactory>(
                c => new OrmLiteConnectionFactory(
                    sqlServerConnectionString, 
                    SqlServerOrmLiteDialectProvider.Instance));

            container.Register<SomeForm>(
                c => new SomeForm(
                    c.Resolve<IDbConnectionFactory>()
                )
            ).ReusedWithin(ReuseScope.None);

        }
    }
}

I like using the lamda in the registration - it defers the construction of objects until they get resolved, rather than at registration time.
By default, the container stores the resolved object as a singleton, but if you have something that needs to be initialized every time it gets used ( ie user controls or winforms ) then use the .ReusedWithin(ReuseScope.None) extension.

Where I need my SomeForm (ie in a button click or whatever)

...
private void btnOpenSomeForm_Click(object sender, EventArgs e)
{
    var myForm = Program.FunqContainer.Resolve<SomeForm>();
    myForm.Show();
}

Check http://blogs.clariusconsulting.net/kzu/mab-containermodel-funq-a-transparent-container/ for more info

As an aside, this also works for VB.net when you put it through http://converter.telerik.com/

Teshatesla answered 19/4, 2013 at 3:14 Comment(0)
T
6

ServiceStack includes an enhanced version of Funq (e.g. with AutoWiring support) that's self-contained in the core ServiceStack.dll.

Unfortunately at this time the ServiceStack.dll is contained in the ServiceStack NuGet package which brings in other ServiceStack server dependencies. You can build it from src or cherry pick from the NuGet package just the dlls you need, i.e:

  • ServiceStack.dll
  • ServiceStack.Common.dll
  • ServiceStack.Interfaces.dll
  • ServiceStack.Text.dll
Tweak answered 5/2, 2013 at 17:38 Comment(3)
Assuming I'm ok with referencing all necessary ServiceStack dll's, how would I configure it to use it from the app? Will autowiring work even though I won't be using ServiceStack's http handlers?Optimistic
Just create a new instance of new Funq.Container() and use the same instance to register and resolve all your deps.Tweak
np :) I've never tried it without an active AppHost instance, but it's fairly self-contained so you shouldn't have any probs. But if you do get any NullReferenceExceptions post them on github.com/ServiceStack/ServiceStack/issues and we'll sort it outTweak
T
3

I'm in a similar position, wanting to use heaps of the ServiceStack tools in a non-webby project. I agree that there is a ... slight lack in documentation for Funq

I have been using it in a legacy WinForms app, trying to avoid changing the original project (too much) and I add the new forms to a new project.
I added references to most of the ServiceStack libraries to most of my projects (manually because I'm doing this in .Net 3.5)

Here is the code in the winforms Program.cs file; Note that the FunqContainer is a public static property - I'm still not sure about that, but it gives access across the whole project to the FunqContainer

using System;
using System.Threading;
using System.Windows.Forms;

using Funq;
using MyApp.Utilities;

static class Program
    {
        public static Funq.Container FunqContainer { get; set; }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            FunqContainer = new Container();
            FunqContainer.Init(); 

            etc...
        }
    }

FunqContainer.Init() is an extension method in my separate project for - you guessed it - initializing Funq

using System.Configuration; // Don't forget to ref System.Configuration.dll
using Funq;     
using ServiceStack.OrmLite;
using ServiceStack.OrmLite.SqlServer;

namespace MyApp.Utilities
{
    public static class FunqExtensions
    {
        public static void Init(this Container container)
        {
            //-------------------------------------------------------
            // NB - I don't particularly like AutoWiring the public properties. 
            // Usually I want private stuff in the constructor)
            //-------------------------------------------------------
            var sqlServerConnectionString = ConfigurationManager.ConnectionStrings["HowdyCS"];
            container.Register<IDbConnectionFactory>(
                c => new OrmLiteConnectionFactory(
                    sqlServerConnectionString, 
                    SqlServerOrmLiteDialectProvider.Instance));

            container.Register<SomeForm>(
                c => new SomeForm(
                    c.Resolve<IDbConnectionFactory>()
                )
            ).ReusedWithin(ReuseScope.None);

        }
    }
}

I like using the lamda in the registration - it defers the construction of objects until they get resolved, rather than at registration time.
By default, the container stores the resolved object as a singleton, but if you have something that needs to be initialized every time it gets used ( ie user controls or winforms ) then use the .ReusedWithin(ReuseScope.None) extension.

Where I need my SomeForm (ie in a button click or whatever)

...
private void btnOpenSomeForm_Click(object sender, EventArgs e)
{
    var myForm = Program.FunqContainer.Resolve<SomeForm>();
    myForm.Show();
}

Check http://blogs.clariusconsulting.net/kzu/mab-containermodel-funq-a-transparent-container/ for more info

As an aside, this also works for VB.net when you put it through http://converter.telerik.com/

Teshatesla answered 19/4, 2013 at 3:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.