0
votes

I have run into a scenario that I would like to solve with Ninject but up until this point none of my work with it has cross this type of situation.

WCF Service App

W3C Log Parsing App (overly simplistic for demonstration purposes).

IW3CLogItem implemented by W3CLogItem W3CLogItem has a public member of type IUrlData (contains the important data but can be one of 5 concrete implementations depending on what it contains).

The decision of which concrete implementation to use is based off of a string match and its constructor takes a regex pattern it will use to parse the data as well as the string to be parsed.

Currently I have a simple factory that does the string comparisons and then calls Create() to return a new concrete object (DocumentUrlItem, DriverUrlItem, AssetUrlItem, etc...).

I was looking at the wiki docs and how to name a binding, but even that only gets me half of the way.

The question I have is: Can this be done without a factory? Can I somehow place a conditional attribute on a binding (i.e. .contains, etc...) that evaluates to true to know which binding to use or am I better off sticking with the factory?

Let elaborate a bit.

If I were to write the factory without ninject in a simplified way, it would look like this:

protected IUrlData Create(string urldata)
{
    if (urldata.Contains("bob"))
    {
        return new BobUrlData(urldata)
    }
    else if (urldata.Contains("tim"))
    {
        return new TimUrlData(urldata);
    }  
}

A couple of things of note:

1) The number of classes that implement IUrlData will grow over time. The strings "tim", and "bob" will be coming from a database.

2) The urldata being passed into BobUrlData and TimUrlData is not the only parameter in the real world, there will also be a regular expression (also sourced from the database which is calculated by the entries timestamp that knows how to handle that particular entry as they have evolved over time.

3) I am really curious if this can be accomplished with Ninject without the need for the factory all together, to somehow through metadata or names achieve the same work but all through bindings all while leaving the code extensible but read-only (other than the binding modules).

2

2 Answers

0
votes

You are able to bind to methods with Ninject.

Ninject Wiki - Contextual Binding

You shouldn't need the factory anymore if you set up the method to return what you need. I can't say one is better than the other though since they both work, but I do prefer the factory doing the work and having that access Ninject to give me the correct implementation. Your result is still the same in the end.

Also, right above on the same page is Specifying Constraints.

0
votes

from a purist point of view, an abstract factory is the correct way to abstract out the implementation from the interface of an object. with that said, ninject offers various ways of implementing what you want without using an abstract factory. The ones that I feel will help you most are ToMethod and providers