Bro
Bro

Reputation: 589

Passing Func<Service> vs. Service in constructor

What is the difference between:

private readonly Func<IDataService> _dataServiceCreator;

public FriendDataProvider(Func<IDataService> dataServiceCreator)
{
  _dataServiceCreator = dataServiceCreator;
}

public Friend GetFriendById(int id)
{
  using (var dataService = _dataServiceCreator())
  {
    return dataService.GetFriendById(id);
  }
}

and

private readonly IDataService _dataService;

public FriendDataProvider(IDataService dataService)
{
  _dataService = dataService;
}

public Friend GetFriendById(int id)
{

    return _dataService.GetFriendById(id);
}

The data service used is FileDataSrvice. As i understand there are some pattern differences?

Upvotes: 0

Views: 123

Answers (2)

Alexei Levenkov
Alexei Levenkov

Reputation: 100547

Passing Func<IService> lets one to delay instantiation (or deciding which of instances to use) of interface implementation to the point where it actually needed. Passing IService ties two instances directly for lifetime of your class.

One common usage of Func<IService> is to align lifetimes between different types. Often you have "current Zzzzz" of many that may or may not exist as long as service (i.e. current user, current request, current window) vs. "service that needs Zzzzz" (which can exist for whole apps lifetime) - if you pass Func code that constructed that Func can find "current" instance whenever service needs it.

I.e. in web application if FriendDataProvider is singleton class with application lifetime and implementation of IDataService is request specific then you can let you DI container to create implementation of IDataService on demand with Func version. If you simply pass implementation of IDataService to FriendDataProvider it will pick on tied to some arbitrary request and will not work correctly for subsequent requests.

Upvotes: 2

JamesFaix
JamesFaix

Reputation: 8665

The type Func<T> represents a function that returns a T. So in the first example, each time you want to GetFriendById, you are creating a new service and then using that, whereas the 2nd example uses the same service every time. If you want to avoid holding on to external resources for extended periods of time, the second one might be better.

Upvotes: 3

Related Questions