Как я могу создать экземпляр класса с разрешением из моего метода, используя Unity? - PullRequest
0 голосов
/ 30 декабря 2011

Я использую Unity для создания классов с помощью инжектора конструктора, например:

 public class ProductsController : BaseController
    {
        public ProductsController(
            IService<Account> accountService,
            IService<Product> productService)
        {
            _account = accountService;
            _product = productService;
        }

Загрузчик:

private static IUnityContainer BuildUnityContainer()
        {
            CloudStorageAccount storageAccount;
            storageAccount = CloudStorageAccount.FromConfigurationSetting("DEV_DataConnectionString");
            var container = new UnityContainer();
            container.RegisterType<   IService<Account>, AccountService   >();
            container.RegisterType<   IService<Product>, ProductService   >();
            container.RegisterType<IAzureTable<Product>, AzureTable<Product>>(new InjectionConstructor(storageAccount, "TestProducts"));
            return container;
        }

Теперь мне нужно создать экземпляр экземпляра службы "на лету" из моего метода. Примерно так:

    public void Update(string serviceClassName) {

        var serviceClass = new container.Resolve<IService<Product>>();

Но есть некоторые вещи, которые я не понимаю.

  • Прежде всего мне нужно создать новый контейнер? Я предполагаю, что мне нужно сослаться на контейнер, который я уже создал, но я не могу найти ссылку, как это сделать.
  • Во-вторых, здесь у меня есть жестко закодированный продукт, но мне нужно иметь возможность передать слово «продукт» в качестве параметра и затем создать его.

Как я могу создать свой класс?

Обновление

Пока не тестировалось, но я считаю, что решение для именования моего класса может потребовать, чтобы я зарегистрировал свой класс следующим образом:

container.RegisterType<   IService<Product>, ProductService   >("productService");

Ответы [ 3 ]

0 голосов
/ 30 декабря 2011

Создайте глобальный общедоступный статический класс и добавьте к нему общедоступное статическое свойство unitycontainer. Тогда вы можете использовать его во всем мире.

Для создания класса ... вы можете использовать отражение следующим образом:

public static class MyContainer
{
    public static UnityContainer Container { get; set; }
}

class ServiceClass<T>
{}

class ReturnClass
{}

class Program
{
    static void Main(string[] args)
    {

    }

    ReturnClass DoResolve(string name)
    {
        Type type = typeof (UnityContainer);
        MethodInfo genericMethod = type.GetMethod("Resolve").MakeGenericMethod(typeof(ServiceClass<>).MakeGenericType(new Type[]{Type.GetType(name)}));
        object invoke = genericMethod.Invoke(MyContainer.Container,null);
        return (ReturnClass) invoke;
    }
}

И после этого вы можете просто вызвать этот DoResolve () ...

Надеюсь, я чем-то помог.

0 голосов
/ 31 декабря 2011

Почему вы используете волшебную строку для отправки обновлений в службу?Если вы знаете строку на стороне клиента, вы также можете вызвать соответствующий метод обслуживания UpdateProduct (...) , UpdateCustomer (...) .И тогда вам не понадобятся какие-либо догадки на стороне службы.

0 голосов
/ 30 декабря 2011

Почему бы не использовать обобщения, а не использовать строки:

public void Update<T>(T item) {
    var serviceClass = container.Resolve<IService<T>>();
    serviceClass.DoSomething();
}

Использование:

Update(someProduct); 
// generic type is inferred. Same as - Update<Product>(someProduct)

Я считаю, что вы можете получить ссылку на свой контейнер, добавив в конструктор зависимостьтип IUnityContainer - см. Может ли контейнер единицы передавать свою ссылку в качестве параметра конструктора?

...