Conventional Dependency Injection with Autofac

Instead of containing a definition or hello-world Autofac basics, this article will focus on bringing new aspect to registration and composition root that we currently use on some projects at Trendyol

Continue reading Conventional Dependency Injection with Autofac

Advertisements

Derinlemesine Garbage Collector

Merhabalar,

Araştırmalarım sonucunda .Net dünyasında anlaşılması itibariyle kanayan yaralarımızdan biri olan Garbage Collector’a ait Türkçe pek bir kaynak bulunmamasından ötürü bu konu hakkında Türkçe bir çalışma yapmak istedim. Araştırmalarım süresince edindiğim bilgileri topladım kendi yorumlarımı da katarak böyle bir makale yazmaya karar verdim.

Uyarı: Uzun bir yazı olacak, yanında çay, kola, kahve gibi enerji verici veya dinç tutan şeyler eşliğinde okumanızı tavsiye ederim:)

Bir Managed(Yönetilebilir) process içinde iki çeşit heap vardır. Native ve Managed heap. Native heap VirtualAlloc Windows Api’si tarafından yönetilir ve işletim sistemi tarafından kullanılan bir heap’tir. Diğeri ise Managed Heap; bu CLR tarafından yönetilir. CLR Garbage Collector’ü çağıran birimdir.

Continue reading Derinlemesine Garbage Collector

Aspect oriented Request Object(DTO) Validation in WCF with FluentValidation and CastleWindsor

In this post we will look at the how to automate FluentValidation on WCF or other service structures. As you know, FluentValidation tool has developed by Jeremy Skinner.
It is a very good and useful tool for validation for MVC controller’s actions.
So I thought, Why we can not use FluentValidation in WCF service calls, in DDD RequestDTO’s or anywhere.

First of all, I’m doing whole operations via these tools;

  • Castle Windsor 3.3.0.0
  • FluentValidaton 6.1.0.0

You can use your own IOC container, but your IOC container should be support the interceptors.
So, let’s get start;

Lets assume I have a web service named “MobileService”. It is implemented from IMobileService.

[ServiceContract]
public interface IMobileService
{
    [OperationContract]
    [ValidateWithRule(ValidatorRuleSet.CashOrderMerchantRule, ValidatorRuleSet.CashOrderProductRule)]
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json)]
    CashOrderResponse CashOrder(CashOrderRequest request);
}

This mobile service is exposed upon as an endpoint

http://127.0.0.1/MobileService

via CastleWindsor WCF IntegrationFacility.
Now, we are gonna define rules via FluentValidation for our “CashorderRequest”.

public class ValidatorBase<T> : AbstractValidator<T> where T : RequestBase
{
    public ValidatorBase()
    {
        RuleFor(x => x.LanguageCode)
            .NotNull().WithMessage("LanguageCode cannot be null")
            .NotEmpty().WithMessage("LanguageCode cannot be empty or null");

        RuleFor(x => x.TerminalCode)
            .NotNull().WithMessage("TerminalCode cannot be null")
            .NotEmpty().WithMessage("TerminalCode cannot be empty or null");

        RuleFor(x => x.TerminalSerialNumber)
            .NotNull().WithMessage("TerminalSerialNumber cannot be null")
            .NotEmpty().WithMessage("TerminalSerialNumber cannot be empty or null");

        RuleFor(x => x.TrackId)
            .NotNull().WithMessage("TrackId cannot be null")
            .Must(x => x != Guid.Empty).WithMessage("TrackId cannot be empty GUID!");

        RuleFor(x => x.TransactionDateTime).Must(t =>
                {
                    DateTime dateTime;
                    return DateTime.TryParse(t, out dateTime);
                }).WithMessage("Please fill CreateDateTime correctly!");
    }
}
public class CashOrderRequestValidator : ValidatorBase<CashOrderValidator>
{
    public CashOrderRequestValidator()
    {
        RuleSet(ValidatorRuleSet.CashOrderMerchantRule, () =>
        {
             RuleFor(x => x.OwnerDealerCode)
                .NotNull().WithMessage("Merchant Dealercode cannot be null");

             RuleFor(x => x.OwnerTerminalCode)
                .NotNull().WithMessage("Merchant TerminalCode cannot be null");
        });

        RuleSet(ValidatorRuleSet.CashOrderProductRule, () =>
        {
                RuleFor(x => x.OrderDetails)
                .Must(x => x.Count > 0).WithMessage("CashOrder must be contains at least 1 item!")
                .NotNull().WithMessage("Order has to contains at least one product!")
                .Must(x => x.TrueForAll(p => p.Quantity > 0))
                .WithMessage("Product quantity must be greather than 0!");
        });
    }
}

The CashOrderValidator has two rulesets. Sometimes you can use same DTO or request object for multiple methots. In this case you should pass some kind of attributes on method interfaces in order to specify which method in with which rule is will be checked.

[ValidateWithRule(ValidatorRuleSet.CashOrderMerchantRule,ValidatorRuleSet.CashOrderProductRule)]
    public class ValidateWithRuleAttribute : Attribute
    {
        public ValidateWithRuleAttribute(params string[] ruleSets)
        {
            this.RuleSetNames = ruleSets;
        }

        private string[] RuleSetNames { get; set; }
    }
    

If you don’t want to that, maybe you wanna make all of your validation without rulesets (you may not need them) there is no problem with that.
FluentValidator can run any Rule which not inside any rulesets. So,thus ValidateWithRule attibute is not necessary on every method interfaces. It is specific for use.
So after implementation of validators, you should register this components on Castle Windsor container.

public class ValidatorInstallers : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Classes.FromAssemblyContaining(typeof(ValidatorBase<>))
            .IncludeNonPublicTypes()
            .BasedOn(typeof(IValidator<>))
            .WithServiceAllInterfaces()
            .LifestyleTransient());
    }
}

If you look to that AbstractValidator <T> implementation, it is implemented from IValidator<T> and IValidator both.
So this situation saves the register conventions to Castle Container. Which means, you can register all Request Validators only above statements.
Because all of them implemented from AbstractValidator<T> and besides AbstractValidator<T> implemented from IValidator<T>

Now, we are coming to most important point. So, after this you can ask this question:

“It is good but, Where we are handle this validation execution ?”

For this operation, you should write one interceptor for intercept to the IMobileService requests when invoked.

public class MobileServiceInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        var serviceUrl = ConfigurationManager.AppSettings.Get("MobileServiceHostUrl");
        container.Register(
            Component.For<IMobileService>().ImplementedBy<MobileService>()
                .Interceptors(InterceptorReference.ForType<ExceptionInterceptor>()).AtIndex(0)
                .Interceptors(InterceptorReference.ForType<RequestLoggerInterceptor>()).AtIndex(1)
                .Interceptors(InterceptorReference.ForType<ValidatorInterceptor>()).AtIndex(2)
                .LifeStyle.PerWcfOperation()
                .AsWcfRestfulService(serviceUrl, 3));
    }
}

You can see ValidatorInterceptor at index 2 at the above. Well, all trick is in the this interceptor implementation.

public class ValidatorInterceptor : IInterceptor
{
    public ValidatorInterceptor(IKernel kernel)
    {
        _kernel = kernel;
    }

    private IKernel _kernel { get; set; }

    public void Intercept(IInvocation invocation)
    {
        AssertRequest(invocation);
        invocation.Proceed();
    }
    //Get rulesets if any passed the method interface via Attribute.
    private static string[] GetOrDefaultValidatorRuleSets(MethodInfo method)
    {
        var rules = new List<string>{ "default" };
        var attribute = method.CustomAttributes.FirstOrDefault(x =>x.AttributeType == typeof(ValidateWithRuleAttribute));
        if (attribute == null)
            return rules.ToArray();

        rules.AddRange((attribute.ConstructorArguments.First().Value as ReadOnlyCollection<CustomAttributeTypedArgument>)
                .Select(x => x.Value.ToString())
                .ToList());
        return rules.ToArray();
    }
    //Static typed validator method.
    private static ValidationResult ValidateTyped<T>(IValidator<T> validator, T request, string[] ruleset, IValidatorSelector selector = null)
    {
        return validator.Validate(request, selector: selector, ruleSet: string.Join(",",ruleset).TrimEnd(','));
    }

    private void AssertRequest(IInvocation invocation)
    {
        var requestObject = invocation.Arguments[0];
        var ruleSets = GetOrDefaultValidatorRuleSets(invocation.Method);

        // We are finding request object validator intance  !!! This is important.
        var requestValidatorType = typeof(IValidator<>).MakeGenericType(requestObject.GetType());

        var validator = _kernel.Resolve(requestValidatorType);

        if (validator == null)
            return;

        // We cannot cast IValidator<CashOrderRequest> because we cannot pass CashOrderRequest type
        //like as _kernel.Resolve(requestValidatorType)  as IValidator<????requestObject.GetType()> fail!!!
        //So we should use "MakeGenericMethod" invocation and this way we can pass request object type dynamically.
        var validationResult = GetType().GetMethod("ValidateTyped", BindingFlags.Static | BindingFlags.NonPublic)
             .MakeGenericMethod(requestObject.GetType())
             .Invoke(null, new[] { validator, requestObject,ruleSets, null }) as ValidationResult;

        _kernel.ReleaseComponent(validator);

        if (validationResult != null && validationResult.IsValid)
             return;

        if (validationResult != null && validationResult.Errors.Any())
            throw new BusinessException(string.Join(",",validationResult.Errors.Select(x => x.ErrorMessage)));
    }
}

I hope it will be helpful.
Happy Coding!

DynamicTranslator v3 Yayınlandı

Performans iyileştirmeleri, kod refactorlerinin yer aldığı bir versiyon oldu.

Not: Eğer çalıştıramayan varsa, microsoft .net 4.6 sürümü bilgisayarınızda yüklü olmadığındandır. Projeyi C# 6.0 ve .net framework 4.6 da yazıyorum. O yüzden .net 4.6 bileşeni yüklü olmayan bilgisayarlarda açılmayacaktır. Zaten ilk çalıştırmak için “DynamicTranslator.exe” ‘ye bastığınızda yükleme uyarısı çıkacaktır “Evet” diyerek oradan yükleyebilir veya aşağıdaki .net 4.6 linkini kullanabilirsiniz.

Sırasıyla;

Sağlıcakla 🙂

Araya da bir görsel sıkıştıralım 🙂

dynamictranslatorv3

Dynamic Translator v2 Yayınlandı | Dynamic Translator v2 Published

Merhabalar,

DynamicTranslator V2 yayınlandı 🙂

Bu versiyonda performans iyileştirmeleri ve Google Translate sözlük eklenmesi yapıldı. Artık 4 farklı sözlüğe gidip anlamları birleştiriyor DynamicTranslator.

Başvurulan sözlükler:

  • Google Translate
  • Sesli Sözlük
  • Tureng Sözlük
  • Yandex Çeviri

İndirme Linki : DynamicTranslatorV2

Proje Linki :  Proje (Github)

İstek: Karşılaştığınız hataları bildirirseniz sevinirim, bu programı daha iyi bir düzeye getirmemde yardımcı olacaktır.

Sağlıcakla.