How I can use service Manager in entity class in ZendFramwork2? I just can't get it.
Upd:
I create entity class of user and create method, which loads additional data about it from DB. I would can load this data via table-class if I have instance of serviceManager. But I can't get this instance.
In the Controller I use this code
public function getNewsTable()
{
if (!$this->newsTable)
{
$sm = $this->getServiceLocator();
$this->newsTable = $sm->get('Application\Model\NewsTable');
}
return $this->newsTable;
}
In the Plugin I use
public function getServiceManager()
{
return $this->serviceManager->getServiceLocator();
}
public function setServiceManager(ServiceManager $serviceManager)
{
$this->serviceManager = $serviceManager;
}
But in the entity class it doesn't work.
The entity class needs to impliment "ServiceLocatorAware" interface, and be retrieved by the service locator.
Related
I need to find a way to get an instance of DataProcessingEngine without calling it's constractor.
I am trying to find a way to do so using the registered DataProcessingEngine in composition object (please see the following code). But I could not find a way to do so.
Anyone have a suggestion? Thanks in advance.
public class Composer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Register<IDataProcessingEngine, DataProcessingEngine>(Lifetime.Singleton);
//DataProcessingEngine dataProcessing = compostion.Resolve<IDataProcessingEngine>()??//no resolve function exists in Umbraco.Core.Composing
SaveImagesThread(dataProcessingEngine);
}
public Task SaveImagesThread(IDataProcessingEngine dataProcessingEngine)//TODO - decide async
{
string dataTimerTime = WebConfig.SaveProductsDataTimer;
double time = GetTimeForTimer(dataTimerTime);
if (time > 0)
{
var aTimer = new System.Timers.Timer(time);
aTimer.Elapsed += new ElapsedEventHandler(dataProcessingEngine.SaveImages);
aTimer.Start();
}
return default;
}
}
For all of you who are looking for a way to call a function (that's defined in another class in your code, an Engine or ...) from the composer(where the app starts) and want to avoid calling this function's class' constractor. I've found another way to do so:
public class QueuePollingHandler
{
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
public class SubscribeToQueuePollingHandlerComponentComposer :
ComponentComposer<SubscribeToQueuePollingHandler>
{ }
public class SubscribeToQueuePollingHandler : IComponent
{
private readonly IDataProcessingEngine _dataProcessingEngine;
public SubscribeToQueuePollingHandler(IDataProcessingEngine
dataProcessingEngine)
{
_dataProcessingEngine = dataProcessingEngine;
SaveImagesThread(_dataProcessingEngine);
}
public void SaveImagesThread(IDataProcessingEngine
dataProcessingEngine)
{
....
}
}
And the logic explenation: You create a class (SubscribeToQueuePollingHandlerComponentComposer from the example) and define its base class to be ComponentComposer<Class_that_inherits_IComponent>.
And when you start the application you could see that it gets to the registered class' constractor (SubscribeToQueuePollingHandler constructor).
That's the way that I found to be able to call a function right when the application starts without needing to call its class constractor and actualy use dependency injection.
Can we create a Custom LifeCycle using StructureMap wherein the object has to be in Singleton scope for specified preiod of time, after which the object has to be created again. In short, can we create objects every 20 or 30 mins.
Sure, see e.g. http://www.mikeobrien.net/blog/creating-structuremap-lifecycle-for-wcf/ for an example of how to implement ILifecycle (in this case backed by WCF, but you can just as well make it thread-local, or static). You'll just have to add the logic to return a new IObjectCache instance after x minutes have passed.
Copy/paste of the code there:
public class WcfOperationLifecycle : ILifecycle
{
public static readonly string ITEM_NAME = "STRUCTUREMAP-INSTANCES";
public void EjectAll()
{
FindCache().DisposeAndClear();
}
public IObjectCache FindCache()
{
if (!OperationContext.Current.OutgoingMessageProperties.ContainsKey(ITEM_NAME))
OperationContext.Current.OutgoingMessageProperties.Add(ITEM_NAME, new MainObjectCache());
return (IObjectCache)OperationContext.Current.OutgoingMessageProperties[ITEM_NAME];
}
public string Scope { get { return "WcfOperationLifecycle"; } }
}
Say I have a list of protocol handlers, and the client service knows which protocol to use based on an enum value, it would be nice to selected the protocol from the list of i/fs passed in.
How can I achieve this in StructureMap?:
public EmailTransportService(interfaces...,
IDictionary<EmailAccountType, IEmailTransportHandler> transportHandlers)
At the moment, I'm using ObjectFactory with get named instance like so:
_emailTransportHandlers = new Dictionary<EmailAccountType, string>
{
{EmailAccountType.Pop3, "Pop3Handler"},
{EmailAccountType.IMAP, "IMapHandler"}
};
then resolving like so:
private IEmailTransportHandler GetTransportHandler(EmailAccountType accountType)
{
return ObjectFactory.GetNamedInstance<IEmailTransportHandler>(_emailTransportHandlers[accountType]);
}
but I don't like this as its difficult within my unit tests to verify the calls to the handlers.
My service registry looks like so:
public EmailTransportServiceRegistry()
{
Scan(x =>
{
....
});
For<IEmailTransportHandler>().Use<ActiveUpPop3Handler>().Named("Pop3Handler");
For<IEmailTransportHandler>().Use<ActiveUpIMap4Handler>().Named("IMapHandler");
}
So basically I'm relying on named instances based on the dictionary list of protocol types.
My solution was to have a static register method from the client service like so:
public static IDictionary<EmailAccountType, IEmailTransportHandler> RxHandlerRegistration()
{
return new Dictionary<EmailAccountType, IEmailTransportHandler>
{
// following registrations use ActiveUp library for pop3/imap (http://mailsystem.codeplex.com/)
{EmailAccountType.Pop3, ObjectFactory.GetInstance<ActiveUpPop3Handler>()},
{EmailAccountType.IMAP, ObjectFactory.GetInstance<ActiveUpIMap4Handler>()}
};
}
Then in the ServiceRegistry class:
public class EmailTransportServiceRegistry : ServiceRegistry
{
public EmailTransportServiceRegistry()
{
// other registries...
For<IDictionary<EmailAccountType, IEmailTransportHandler>>().Use(x => EmailTransportService.RxHandlerRegistration());
}
}
I've got a class hierarchy like this (simplified):
class Connection
{
}
interface IService<T>
{
}
class ServiceImplementation : IService<int>
{
public ServiceImplementation(Connection)
{
}
}
interface IConnectionConfiguration
{
public void Configure(Connection c)
}
class ConnectionConfiguration : IConnectionConfiguration
{
public void Configure(Connection c)
}
Where I have multiple implementations of IConnectionConfiguration and IService. I am wanting to create a provider/bindings which:
constructs a new instance of Connection.
GetAll and applies that to the Connection.
Bindings specify which IConnectionConfiguration implementations to be used, based on
on the type of IService to be constructed
Currently I have a provider implementation like this:
public Connection CreateInstance(IContext context)
{
var configurations = context.Kernel.GetAll<IConnectionConfiguration>()
var connection = new Connection();
foreach(var config in configurations)
{
config.Configure(connection);
}
return connection;
}
But when I try to make the contextual binding for IConnectionConfiguration it doesn't have a parent request or parent context...
Bind<IConnectionConfiguration>().To<ConcreteConfiguration>().When(ctx => {
// loop through parent contexts and see if the Service == typeof(IService<int>);
// EXCEPT: The ParentRequest and ParentContext properties are null.
});
What am I doing wrong here? Can I do this with ninject?
By calling kernel.GetAll you are creating a new request. It has no information about the service context. There is an extension that allows you to create new requests that preserve the original context (Ninject.Extensions.ContextPreservation)
See also https://github.com/ninject/ninject.extensions.contextpreservation/wiki
context.GetContextPreservingResolutionRoot().GetAll<IConnectionConfiguration>();
Imagine there is a Customer class with an instance Load() method.
When the Load() method is called, it retrieves order details by e.g.
var orders = Order.GetAll(customerId, ...);
GetAll() is a static method of the Order class and the input parameters are fields defined in the Customer class.
As you can see, Order is a dependency of the Customer class, however, I can't just create an IOrder and inject it there as interfaces can't have static methods.
Therefore, the question is how could I introduce dependency injection in this example?
I don't want to make GetAll() an instance method since it's a static method and need to keep it that way.
For example, I have used utility classes in my design, most of which just contain static methods.
If you must keep the static method, I would wrap the static calls in a Repository object.
Like this:
interface IOrderRepository {
IEnumerable<IOrder> GetAll(customerId, ..);
}
class OrderRepository : IOrderRepository {
IEnumerable<IOrder> GetAll(customerId, ...)
{
Order.GetAll(customerId,...); // The original static call.
}
}
Now you inject this repository into your Customer class.
(I'm assuming you're doing this so you can inject fake IOrders at runtime for testing purposes. I should say that in general, static methods are a serious obstacle to testing.)
Seeing as your aggregate root for fetching orders is your customer model I would strongly advise you create a customer repository and inject that to whatever service requires it.
Here is an example:
public class CustomerService
{
private readonly ICustomerRepository _customerRepository;
public CustomerService(ICustomerRepository customerRepository)
{
if (customerRepository == null)
{
throw new ArgumentNullException("customerRepository");
}
_customerRepository = customerRepository;
}
public IEnumerable<IOrder> GetOrdersForCustomerId(int customerId)
{
return _customerRepository.GetOrdersForCustomerId(customerId);
}
}
public interface ICustomerRepository
{
IEnumerable<IOrder> GetOrdersForCustomerId(int customerId);
}
class CustomerRepository : ICustomerRepository
{
public IEnumerable<IOrder> GetOrdersForCustomerId(int customerId)
{
throw new NotImplementedException();
}
}
Function Pointer Injection
TLDR:
Inject a function pointer into the Customer class. The value of this function pointer can be Order.GetAll in production, and MockOrder.GetAll in tests.
EXAMPLE:
The dependency (problematic static function we depend on):
class Order {
static func GetAll() -> [Order] {
var orders = ... // Load from production source
return orders
}
}
Our dependent class (depends on static function):
class Customer {
func Init(getAllOrdersFunction) { // Arg is a func pointer
self.getAllOrdersFunction = getAllOrdersFunction
}
func Load() {
var orders = self.getAllOrdersFunction()
// Do stuff...
}
}
Production client class (performs the dependency injection):
class BusinessLogicManager {
func DoBusinessLogic() {
var customer = Customer(Order.GetAll) // Prod func injected here
customer.Load()
// Do stuff...
}
}
Testing client class (how unit test can inject a fake dependency):
class CustomerUnitTests {
static func GetFakeOrders() {
var orders = ... // Hardcoded test data
return orders
}
func TestLoad() {
var customer = Customer(CustomerUnitTests.GetFakeOrders) // Fake func injected here
customer.Load()
// Verify results given known behavior of GetFakeOrders
}
}
DISCUSSION:
How you actually inject the "function pointer" will depend on the syntax and features available in your language. Here I'm just talking about the general concept.
This isn't exactly a pretty solution. It would probably be easier if you can change GetAll to be an instance method (perhaps by introducing an OrdersLoader object, or by using Paul Phillips' answer). But if you really want to keep it as a static function, then this solution will work.