как правильно отделить особенности реализации от библиотек классов в .net - PullRequest
1 голос
/ 03 августа 2011

Мне интересно, существует ли стандартный способ в c # (или, может быть, даже в cli) для эффективного разделения логики реализации на отдельные библиотеки / сборки классов, которые будут динамически загружаться процессом, который будет предварительно выполнять действия над этими библиотеками на основеобщий интерфейс.

Точнее: скажем, я создаю сервис, который принимает сообщения и делегирует обработку этих сообщений чему-то другому.Что-то вроде:

while(true){
   message = read_message_from_somewhere();
   class_from_another_lib.do_somthing_with_Message(message); 
}

Я хочу, чтобы процесс загружал класс lib во время выполнения из какой-то конфигурации.В библиотеке, я полагаю, был бы некоторый основной класс или фабрика классов, которая реализует некоторую интерфейсную часть, которая выглядит следующим образом:

ISomePublicIface{
   void do_somthing_with_Message(messageT);
}

Все это выглядит как Java, но все, что мне нужно было бы сделать, этокласс в сборке, реализующий своего рода интерфейс для инъекций, добавляет строку в конфигурацию приложения и получает множество вещей бесплатно.

Ответы [ 2 ]

6 голосов
/ 03 августа 2011

Взгляните на Managed Extensibility Framework (MEF) , который включен в .NET 4.0.MEF может динамически загружать и вставлять компоненты из внешних DLL.

1 голос
/ 03 августа 2011

Если вам нравится решение NIH ... Я написал несколько подробную версию этой проблемы, которая позволяет вам использовать DI-контейнер для хранения обработчиков для сообщения и отправки в соответствующий обработчик на основе сообщения. Я использовал autofac для контейнера, но все должно быть подходящим, если оно может разрешить открытые дженерики:

// Message marker interface
interface IMessage {}

// Message handler interface
interface IHandles<T> where T: IMessage
{
    void Handle(T message);
}

// A message which defines mooing
class MooMessage : IMessage {}

// A message which defines woofing
class WoofMessage : IMessage {}

// A handler for moo messages
class MooHandler : IHandles<MooMessage>
{
    public void Handle(MooMessage message)
    {
        Console.WriteLine("moo");
    }
}

// A handler for woof messages
class WoofHandler : IHandles<WoofMessage>
{
    public void Handle(WoofMessage message)
    {
        Console.WriteLine("woof");
    }
}

class Program
{
    // Generate some test messages
    static IEnumerable<IMessage> MessageGenerator()
    {
        yield return new WoofMessage();
        yield return new MooMessage();
    }

    static void Main(string[] args)
    {
        // configure container
        var builder = new ContainerBuilder();
        // Register message handlers here through configuration or convention...
        builder.RegisterType<WoofHandler>().AsImplementedInterfaces();
        builder.RegisterType<MooHandler>().AsImplementedInterfaces();
        var container = builder.Build();

        // handle all messages until done
        foreach (var message in MessageGenerator())
        {
            // resolve the handler for the message from the container
            var handler = container
                .Resolve(typeof(IHandles<>)
                .MakeGenericType(message.GetType()));

            // call the handler - you have to do this using reflection unfortunately
            // due to the nature of open generics.
            handler
                .GetType()
                .GetMethod("Handle")
                .Invoke(handler, new object[] { message });
        }
    }
}

Вы, очевидно, захотите немного извлечь проблемы из Main, но это должно дать вам суть проблемы и решения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...