Pergunta

Deixe -me descrever o problema e a solução que tenho atualmente e talvez você possa me ajudar a esclarecer por que é uma má idéia (assumindo que seja) e o que posso fazer para torná -lo um sistema melhor.

No momento, tenho 600 "Rippers" que analisam os arquivos e os rasgam para CSV ou outros formatos. Todos os Rippers implementam uma interface comum e classe base. No momento em que um trabalho é filmado, dependendo da configuração desse trabalho, um estripador específico é chamado usando reflexão.

            foreach (var stream in streams)
            {
                try
                {
                    // load it
                    Assembly asm = Assembly.LoadFile(Path.Combine(stream.RipperPath, stream.RipperFileName), new Evidence());
                    if (asm == null)
                    {
                        MessageBox.Show(String.Format("Invalid Interface ripper loaded.\n{0}", Path.Combine(stream.RipperPath, stream.RipperFileName)));
                        return;
                    }

                    foreach (Type objType in asm.GetTypes())
                    {
                        if (!objType.IsPublic)
                            continue;

                        // make sure the type isn't Abstract
                        if (((objType.Attributes & TypeAttributes.Abstract) == TypeAttributes.Abstract))
                            continue;

                        // IRipper is the interface that all of the Rippers must implement to be loaded
                        Type objInterface = objType.GetInterface("IRipper", true);
                        if (objInterface == null)
                            continue;

                        try
                        {
                            var iri = (IRipper)Activator.CreateInstance(objType);

                            // Rippers must register with their hosts
                            iri.Host = this;
                            iri.OnStart += RipperStart;
                            iri.OnComplete += RipperComplete;
                            iri.OnProgressChanged += RipperStatusUpdate;
                            iri.dataStream = stream;
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(String.Format("Error loading interface: {0}\n{1}", Path.Combine(stream.RipperPath, stream.RipperFileName), ex.Message));
                }
            } 

Todos os Rippers implementam uma função chamada "RIP ()", que a interface os contrata.

Usando o código atual O único problema que posso ver é que, depois de carregar 600 conjuntos (já que eles são carregados quando necessários), começará a ficar um pouco lento se não forem descarregados depois de terem sido usados.

O que você sugeriria?

Foi útil?

Solução

Na verdade, você tem 600 Rippers diferentes, ou 600 fluxos e um número menor de Rippers? Você realmente precisa que cada estripador esteja em sua própria assembléia? Se você pudesse agrupar os Rippers, poderá ter muito menos montagens. Se os detalhes do seu fluxo contrariam o nome do tipo e o executável, você poderá ter vários Rippers e não precisará procurar a assembléia para eles - basta ligar Assembly.GetType.

Não sei quanto sobrecarga realmente existe por montagem, lembre -se - eu esperaria que 600 assembléias ocupem uma quantidade razoável de memória, mas não afetei o desempenho muito além disso.

A abordagem geral parece razoável, embora você também possa querer olhar para o Estrutura de extensibilidade gerenciada (MEF) - Pode ser um exagero para o seu caso, mas vale a pena dar uma olhada. A outra coisa que eu faria é levar em consideração o código "Obtendo um Estripador" do código "Processando um fluxo" :)

Outras dicas

Você pode querer dar uma olhada no System.addin material. Parece que os complementos são carregados em seus próprios domínios de aplicativos, o que possibilita descarregá-los de maneira limpa quando não são mais necessários.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top