Как использовать ServiceStack Funq в своих проектах

На работе мы делаем несколько новых проектов веб-сервисов в ServiceStack и в некоторых из них используем Funq. В настоящее время я работаю над отдельным проектом, который будет использовать указанные веб-службы, и мне было интересно, есть ли способ использовать Funq ServiceStack в моем проекте для разрешения моих зависимостей, чтобы использовать более или менее те же шаблоны, которые мы используем, когда разработка наших веб-сервисов.

Это возможно?


person enriquein    schedule 05.02.2013    source источник
comment
Почему вы думаете, что это невозможно? Funq — это контейнер внедрения зависимостей. Вы можете добавить его в любой проект.   -  person Daniel Hilgarth    schedule 05.02.2013
comment
Поскольку документации по исходному проекту нет, я даже не знаю, с чего начать. Кроме того, мне было интересно использовать версию, упакованную с ServiceStack, а не версию на CodePlex.   -  person enriquein    schedule 05.02.2013


Ответы (2)


Я нахожусь в аналогичном положении, желая использовать кучу инструментов ServiceStack в не-сетевом проекте. Я согласен, что есть ... небольшой недостаток в документации для Funq

Я использовал его в устаревшем приложении WinForms, пытаясь избежать изменения исходного проекта (слишком сильного), и добавляю новые формы в новый проект.
Я добавил ссылки на большинство библиотек ServiceStack в большинство своих проектов. (вручную, потому что я делаю это в .Net 3.5)

Вот код в файле winforms Program.cs; Обратите внимание, что FunqContainer является общедоступным статическим свойством — я до сих пор не уверен в этом, но он дает доступ ко всему проекту к 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() — это метод расширения в моем отдельном проекте для — как вы уже догадались — инициализации 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);

        }
    }
}

Мне нравится использовать лямбда при регистрации — она откладывает построение объектов до их разрешения, а не во время регистрации.
По умолчанию контейнер хранит разрешенный объект как синглтон, но если у вас есть что-то, что нужно быть инициализирован каждый раз, когда он используется (например, пользовательские элементы управления или winforms), затем используйте расширение .ReusedWithin(ReuseScope.None).

Где мне нужен мой SomeForm (т.е. по нажатию кнопки или что-то в этом роде)

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

Проверьте http://blogs.clariusconsulting.net/kzu/mab-containermodel-funq-a-transparent-container/ для получения дополнительной информации

Кроме того, это также работает для VB.net, когда вы передаете его через http://converter.telerik.com/

person JonFA    schedule 19.04.2013

ServiceStack включает расширенную версию Funq (например, с поддержкой AutoWiring), которая является автономной в ядре ServiceStack.dll.

К сожалению, в настоящее время ServiceStack.dll содержится в пакете NuGet ServiceStack, который включает другие зависимости сервера ServiceStack. Вы можете собрать его из src или выбрать из пакета NuGet только те DLL, которые вам нужны, то есть:

  • ServiceStack.dll
  • ServiceStack.Common.dll
  • ServiceStack.Interfaces.dll
  • ServiceStack.Text.dll
person mythz    schedule 05.02.2013
comment
Предполагая, что я могу ссылаться на все необходимые библиотеки DLL ServiceStack, как мне настроить его для использования из приложения? Будет ли работать автосвязывание, даже если я не буду использовать обработчики http ServiceStack? - person enriquein; 05.02.2013
comment
Просто создайте новый экземпляр new Funq.Container() и используйте тот же экземпляр для регистрации и разрешения всех ваших зависимостей. - person mythz; 06.02.2013
comment
Спасибо, Демис. Я попробую. - person enriquein; 06.02.2013
comment
np :) Я никогда не пробовал его без активного экземпляра AppHost, но он довольно автономен, поэтому у вас не должно быть никаких проблем. Но если вы получаете какие-либо NullReferenceExceptions, разместите их на github.com/ServiceStack/ServiceStack/issues и мы разберемся - person mythz; 06.02.2013