Как я знаю, это невозможно с Кварцем, я боролся с теми же проблемами, и единственное решение, которое я нашел, было использовать ServiceLocator и явно создать область действия в Задании.
Я закончил с чем-то вроде этого:
// Pseudo-Code
public class MyJob : IJob
{
private readonly IServiceLocator _serviceLocator;
public MyJob(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
}
public async Task Execute(JobExecutionContext context)
{
using(_serviceLocator.BeginScope())
{
var worker = _serviceLocator.GetService<MyWorker>();
await worker.DoWorkAsync();
}
}
}
В этом случае ваш работник все еще ограничен, но работа больше не. Таким образом, вы по-прежнему можете использовать ваш Worker в других местах вашего решения, и область все еще работает. Вам необходимо внедрить ServiceLocator самостоятельно в зависимости от используемого вами DI, и IServiceLocator
также должен быть вами определен.
Редактировать
В одном из наших проектов мы используем это:
/// <summary>
/// A simple service locator to hide the real IOC Container.
/// Lowers the anti-pattern of service locators a bit.
/// </summary>
public interface IServiceLocator
{
/// <summary>
/// Begins an new async scope.
/// The scope should be disposed explicitly.
/// </summary>
/// <returns></returns>
IDisposable BeginAsyncScope();
/// <summary>
/// Gets an instance of the given <typeparamref name="TService" />.
/// </summary>
/// <typeparam name="TService">Type of the requested service.</typeparam>
/// <returns>The requested service instance.</returns>
TService GetInstance<TService>() where TService : class;
}
Мы используем в основном SimpleInjector с этой реализацией:
/// <summary>
/// SimpleInjector implementation of the service locator.
/// </summary>
public class ServiceLocator : IServiceLocator
{
#region member vars
/// <summary>
/// The SimpleInjector container.
/// </summary>
private readonly Container _container;
#endregion
#region constructors and destructors
public ServiceLocator(Container container)
{
_container = container;
}
#endregion
#region explicit interfaces
/// <inheritdoc />
public IDisposable BeginAsyncScope()
{
return AsyncScopedLifestyle.BeginScope(_container);
}
/// <inheritdoc />
public TService GetInstance<TService>()
where TService : class
{
return _container.GetInstance<TService>();
}
}
[1110 ] Как видите, это простая оболочка, которая помогает скрыть настоящую DI Framework от потребителей. Я надеюсь, что это поможет немного понять вашу необходимую реализацию.
Для GridView вы можете использовать метод setOnItemClickListener, чтобы иметь прослушиватель OnItemClickListener. Этот слушатель даст вам метод, который вы должны переопределить с помощью подписи
onItemClick(AdapterView<?> parent, View v, int position, long id)
, где вы получите позицию элемента в сетке, по которой щелкнули, и представление, которое находится внутри ячейки сетки. Это то, что вам нужно?
Мне удалось получить позицию изображения, по которому щелкнули мышью, установив окончательную позицию и добавив прослушиватель onClick в imageView , Здесь регистрируется положение изображения, по которому щелкнули.
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d("onClick","position ["+position+"]");
}
});
}
else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}