views:

171

answers:

2

Hi folks,

I've got an interface which i've used StructureMap to Dependency Inject.

public interface IFileStorageService
{
    void SaveFile(string fileName, byte[] data);
}

The interface doesn't care WHERE the data is saved. Be it to the memory, a file, a network resource, a satellite in space....

So, i've got two classes that implement this interface; a test class and a network file storage class :-

public class TestFileStorageService : IFileStorageService
{ ... etc ...}

public class NetworkFileStorageService : IFileStorageService
{
    public string NetworkUnc { get; set; }
    public void SaveFile(...);
}

Notice how my NetworkFileStorageService has a property? That class requires that value in it's implementation of the SaveFile method.

Well, i'm not sure how to define that property.

I thought i could hard code it where i define my dependency (eg. in my bootstrapper method -> ForRequestedType<IFileStorageService>... etc) but the kicker is .. the business logic DEFINES the location. It's not static.

Finally, because i use interfaces in my logic, this property is not available.

Can anyone help?

If you can, image you want to save two files

  • Name: Test1.bin; location: \server1\folder1
  • Name: Test2.bin; location: \server1\folder2

cheers!

A: 

if this is needed only by this implementation what about putting this in your constructor?

ooo
because I'm not sure how to define that constructor argument _at business logic time_. Remember, it's not a static value .. so how do i 'set' that in the code? I know how to define the constructor args if i was wiring up the DI with ForRequestedType<..> .. but that's not going to help.
Pure.Krome
A: 

Structure map assumes all constructor arguments are required and properties are optional.

There are several ways to solve this with structuremap. You can create a factory method like this

x.ForRequestedType<Func<string, IFileStorageService>>()
  .TheDefault.Is.ConstructedBy(
    () =>
    NetworkUnc  =>
    {
      var args = new StructureMap.Pipeline.ExplicitArguments();
      args.SetArg("NetworkUnc", NetworkUnc );
      return StructureMap.ObjectFactory.GetInstance<IFileStorageService>(args);
    });

now you can create your object with

StructureMap.ObjectFactory
  .GetInstance<Func<string, IFileStorageService>>()("something");

But thats not that pretty. Or create a config class for this class.

public class NetworkFileStorageServiceConfig
{
    public string NetworkUnc { get; set; }
}

and configure it

x.ForRequestedType<NetworkFileStorageServiceConfig>().TheDefault.Is.IsThis(
  new NetworkFileStorageServiceConfig { NetworkUnc  = "something" });

I'm sure there are many other ways to do it too.

AndreasN
i like -- and u probably get the necro award too :)
Pure.Krome