Monday, November 28, 2011

LINQ To LDAP: Logging

I've been working on logging in LINQ to LDAP recently. I added logging support for all requests as well as any errors that occur. I created an interface so that you can integrate your own logging providers.
public interface ILinqToLdapLogger
{
    bool TraceEnabled { get; }

    void Trace(string message);

    void Error(Exception ex, string message = null);
}
Trace is meant for logging query information. I check TraceEnabled before writing information via Trace. Error is always called when exception is encountered. I wasn't sure if I should add logging hooks for error since most projects will handle errors within their own applications, but I figured you could simply ignore calls to Error in your own implementations.

Out of the box I included a basic implementation:
public class SimpleTextLogger : ILinqToLdapLogger
{
    private readonly TextWriter _textWriter;

    public SimpleTextLogger(TextWriter textWriter)
    {
        _textWriter = textWriter;
        TraceEnabled = true;
    }

    public bool TraceEnabled { get; set; }

    public void Trace(string message)
    {
        _textWriter.WriteLine(message);
    }

    public void Error(Exception ex, string message = null)
    {
        if (message != null) _textWriter.WriteLine(message);
        ObjectDumper.Write(ex, 0, _textWriter);
    }
}
This is mainly used for debugging support, but it also serves as an example implementation. Here's another example using Common.Logging .Net which offers a lot more support for different logging frameworks:
public class CommonLogger : ILinqToLdapLogger
{
    private ILog _errorLog;
    private ILog _traceLog;

    public CommonLogger()
    {
        _traceLog = LogManager.GetLogger("trace");
        _errorLog = LogManager.GetLogger("error");
    }

    public void Trace(string message)
    {
        _traceLog.Trace(message);
    }

    public void Error(Exception ex, string message = null)
    {
        _errorLog.Error(message, ex);
    }

    public bool TraceEnabled
    {
        get { return _traceLog.IsTraceEnabled; }
    }
}
You can attach a log directly to a DirectoryContext or through the LdapConfiguration so it can be used with the ConncectionFactory as well. I'll go into more detail in my next post about the LdapConfiguration changes.
var context = new DirectoryContext() 
{
     Logger = new SimpleTextLogger(Console.Out)
};

var config = new LdapConfiguration()
     .LogTo(new SimpleTextLogger(Console.Out));

//will inject the logger for you
context = config.CreateContext();

Friday, November 11, 2011

LINQ To LDAP: NuGet

LINQ to LDAP 2.0.2 has been released over at codeplex. I've also finally made the jump to NuGet. Happy day!

Thursday, November 10, 2011

LINQ To LDAP: More Control

Currently paging and sorting controls will automatically be created for the by the framework. That's nice for most situations, but sometimes you need a little more control.

I added a WithControls extension method that allows you to specify as many additional DirectoryControls as necessary.

List<User> list = context.Query<User>()
    .WithControls(new DirectoryControl[]
                    {
                        new PageResultRequestControl(100)
                            {
                                IsCritical = true
                            },
                        new SortRequestControl(new[]{new SortKey("cn", null, true)})
                            {
                                IsCritical = true
                            },
                        new ShowDeletedControl
                            {
                                IsCritical = true
                            }
                    })
    .ToList();

If you try to perform an OrderBy or ToPage operation while specifying your own via WithControls then an InvalidOperationException will be thrown.

One cool thing here is behind the scenes I still check if you're requesting a page so you can cast the resulting list as a LdapPage and get the cookie for the next page. And that's about it.

Wednesday, November 9, 2011

LINQ To LDAP: Closing in on 2.0

It's been a while since I've posted. I moved across town, took a vacation, and have just been generally busy. But I'm back and with a few updates about 2.0.

Since the last time I posted, I've made a few API changes and added quite a bit more mapping support. One thing I want to talk about is some tweaks to paging. I've covered ToPage and PageAll in a previous post. PageAll, however, is being deprecated in version 2.0. In it's place you can do this:
//will page all results when enumerated based on the server max page size from LdapConfiguration
context.Query<User>();

//will create a page request for 10 results and stop there
context.Query<User>()
    .Take(10);

//will page all the results in groups of 50
context.Query<User>()
    .InPagesOf(50);

//will create a page request for 2 entries at a time up to a maximum of 10 results
context.Query<User>()
    .Take(10)
    .InPagesOf(2);

In cases when the take size is smaller than the page size, take size will be used.

This is part of the trunk, but is not in the 2.0 beta 2 release. I've updated most of the documentation so you can see a lot of the new stuff over at the codeplex page. I'll also be adding this project to Nuget soon.