Hoe implementeer je een basismethode die voor alle methoden moet worden gebruikt?

Ik heb een productservice. Bij elke oproep aan Service wil ik een methode noemen. In dit geval log ik in. Ik ben op zoek naar een manier om de gebruikstatement in elke methode niet te schrijven. Maar ik wil nog steeds dat het loggen gebeurt bij elk gesprek. Hoe doe ik dit?

    public class ProductService : IProductService
{
    public IList GetProductsByBrand(int BrandID)
    {
        using (new Logging())
        {
           //Get a list of products By Brand
        }
        return new List();
    }

    public IList Search(string ProductName)
    {
        using (new Logging())
        {
           //Search
        }
        return new List();
    }

    public static string OrderProducts(IList Orders, Payment paymentDetials)
    {
        string AuthCode;
        using (new Logging())
        {
           //Order and get the AuthCode
        }
        AuthCode = "";
        return AuthCode;
    }
}
2
Ik begrijp het niet. Wat is de code voor de klasse Logging? Of is dat wat je vraagt? Wat wil je inloggen?
toegevoegd de auteur tallseth, de bron
Ik denk dat wat je vraag moeilijk maakt voor mensen om te begrijpen, is dat je geen verwijzing naar de nieuwe logging-instantie opslaat. Daarom kan het nooit worden aangeroepen in het blok using . Is dit de bedoeling? Wilt u 1) eenvoudigweg een methode bellen vóór elke servicemethode of 2) een instantie maken die wordt doorgegeven en verbruikt door elke servicemethode?
toegevoegd de auteur ErnieL, de bron
Sorry voor de verwarring. Ik wil gewoon een methode vóór elke servicemethode.
toegevoegd de auteur katie77, de bron

3 antwoord

Heb je gehoord van AOP (Aspect Oriented Programming)? Het is een manier om transversale problemen te implementeren als herbruikbare aspecten die het doeltype omwikkelen en aanvullende verwerking uitvoeren vóór of na de methode die ze inpakken.

http://en.wikipedia.org/wiki/Decorator_pattern

Binnen een WCF-omgeving wordt dit meestal gedaan door "Behaviors" toe te passen op uw serviceklasse. In dit geval zou ik de IOperationBehavior-interface willen voorstellen met een kenmerk dat IParameterInspector implementeert om de parameters te bekijken voordat ze worden doorgegeven, de service-instantie wordt gemaakt en aangeroepen. Hier is een link naar een nuttig artikel dat dieper ingaat op uw mogelijkheden om de berichtenpool van de wcf uit te breiden.

http://msdn.microsoft.com/en-us/magazine/cc163302.aspx

//Attribute class
public class LogOperationBehavior : Attribute, IOperationBehavior, IParameterInspector {

public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) {
    return;
}

public void ApplyClientBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.ClientOperation clientOperation) {
    //clientOperation.ParameterInspectors.Add(new ClientParameterInspector());            
}

public void ApplyDispatchBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation) {
    dispatchOperation.ParameterInspectors.Add(this);
}

public void Validate(OperationDescription operationDescription) {
    return;
}



#region IParameterInspector Members

public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) {
   //perform logging after
}

public object BeforeCall(string operationName, object[] inputs) {
    //perform logging before
    return null;
}

#endregion

}

  public class BusinessOperation : IBusinessOperation {

    //Apply to your service via an attribute
    [LogOperationBehavior]
    public DivideResponse DivideTwoNumbers(DivideRequest dr) {            
        return new DivideResponse() {
            Answer = dr.Numerator/ dr.Demoninator2,              
        };
    }
3
toegevoegd
Ik denk dat je toegang zou kunnen krijgen via de IParameterInspector-methoden, omdat deze methoden worden aangeroepen wanneer de service wordt aangeroepen. Ik denk dat de OperationBehavior-methoden worden aangeroepen bij het samenstellen van de servicebeschrijving en geen toegang hebben tot de OperationContext. Ik heb dat niet geprobeerd.
toegevoegd de auteur Jason Turan, de bron
Dit is erg interessant. Ik heb hier een vraag. Niet gerelateerd aan de actuele vraag hierboven. Maar in gedrag, kan ik de OperationContext gebruiken?
toegevoegd de auteur katie77, de bron

Heeft u overwogen om een ​​proxy voor logboeken aan te maken? Het ziet er ongeveer zo uit:

public class LoggingProductService : IProductService
{
    private readonly IProductService _core;

    public LoggingProductService(IProductService core)
    {
        _core = core;
    }

    public IList GetProductsByBrand(int BrandID)
    {
        Log("Getting products for brand " + BrandId);
        return _core.GetProductsByBrand(BrandId);
    }

    //other IProductService methods here, all logging and delegating to _core

    private void Log(string message)
    {
        using (var log = new Logging())
        {
            log.Write(message);
        }
    }
}

Natuurlijk begrijp ik uw Logging-interface niet helemaal, dus vul de juiste gissingen in met de juiste code. Je wilt misschien ook niet een logboek maken en verwijderen dat vaak, ik weet het niet.

1
toegevoegd
Mijn vraag gaat niet over de implementatie van de Logging-interface. In het bovenstaande voorbeeld zou u de methode Log() aanroepen voor alle methoden die door Productservice zijn geïmplementeerd. Mijn vraag is er een manier om het toevoegen van de aanroep Log() aan alle methoden van productservice te voorkomen.
toegevoegd de auteur katie77, de bron

You can create a dynamic proxy. See this article for instructions. http://www.drdobbs.com/windows/184405378

0
toegevoegd